aws cli を使ってS3オブジェクトをglacierにバックアップ

aws ストレージの S3 は、一定期間が過ぎたオブジェクトのストレージを aws Glacier にすることができる。
Glacier にあるオブジェクトはリアルタイムに GET することはできないが、維持コストが安いため、バックアップデータのように普段は不要なデータの保存先に最適。

aws コマンドラインツールの aws cli を使って、バックアップ用の S3 バケットを作成し、特定の prefix のものは一定期間後に Glacier に保存。また、aws cli を使ってGlacier に保存されたオブジェクトをリストアする方法をメモ。

S3-Glacier 連携

以下のリンクを見れば、必要なことは書いてある

Glacierにアーカイブ作成するバケットを作成

バケットの作成

$ aws s3 mb s3://dummy-backup
make_bucket: s3://dummy-backup/

lifecycle 設定

prefix が data/ のオブジェクトは

  • 1日経過すると Glacier にアーカイブ化し (Transition)
  • 2日経過すると 削除(Expiration)

するように設定。(確認のために短くしているだけ。)

$ cat lifecycle.json
{
    "Rules": [
        {
            "Status": "Enabled",
            "Prefix": "data/",
            "Transition": {
                "Days": 1,
                "StorageClass": "GLACIER"
            },
            "Expiration": {
                "Days": 2
            },
            "ID": "Rule for the data/ prefix"
        }
    ]
}
$ aws s3api put-bucket-lifecycle --bucket dummy-backup --lifecycle file://lifecycle.json
$ aws s3api get-bucket-lifecycle --bucket dummy-backup
{
    "Rules": [
        {
            "Status": "Enabled",
            "Prefix": "data/",
            "Transition": {
                "Days": 1,
                "StorageClass": "GLACIER"
            },
            "Expiration": {
                "Days": 2
            },
            "ID": "Rule for the data/ prefix"
        }
    ]
}

検証シナリオ

以下の様なシナリオでアーカイブ化の処理を確認

  • バケットの data/ 以下と data/ 以外にオブジェクトを作成。ストレージは Standard と RRS の両方を利用。
  • 1日後に data/ 以下だけが Glacier に transition していることを確認
  • 2日後に data/ 以下からオブジェクトが expire している(削除されている)ことを確認

オブジェクトのアーカイブ化

オブジェクトの追加

  • ストレージタイプの {STANDARD,REDUCED_REDUNDANCY}
  • KEY が data/ と data/ 以外

の 2×2=4 パターンでオブジェクトを PUT する

$ aws s3 cp --storage-class STANDARD test.png s3://dummy-backup/std.png
upload: ./test.png to s3://dummy-backup/std.png
$ aws s3 cp --storage-class STANDARD test.png s3://dummy-backup/data/std.png
upload: ./test.png to s3://dummy-backup/data/std.png
$ aws s3 cp --storage-class REDUCED_REDUNDANCY test.png s3://dummy-backup/rrs.png
upload: ./test.png to s3://dummy-backup/rrs.png
$ aws s3 cp --storage-class REDUCED_REDUNDANCY test.png s3://dummy-backup/data/rrs.png
upload: ./test.png to s3://dummy-backup/data/rrs.png
$ aws s3api list-objects --bucket dummy-backup --query 'Contents[].{Key: Key, StorageClass: StorageClass, LastModified: LastModified}'
[
    {
        "LastModified": "2014-02-21T16:26:57.000Z",
        "StorageClass": "REDUCED_REDUNDANCY",
        "Key": "data/rrs.png"
    },
    {
        "LastModified": "2014-02-21T16:26:38.000Z",
        "StorageClass": "STANDARD",
        "Key": "data/std.png"
    },
    {
        "LastModified": "2014-02-21T16:26:51.000Z",
        "StorageClass": "REDUCED_REDUNDANCY",
        "Key": "rrs.png"
    },
    {
        "LastModified": "2014-02-21T16:26:21.000Z",
        "StorageClass": "STANDARD",
        "Key": "std.png"
    }
]

transition 後

1日後には transition が発生する。
プリフィックスが /data のデータだけが Glacier に transition していることを確認。

$ aws s3api list-objects --bucket dummy-backup --query 'Contents[].{Key: Key, StorageClass: StorageClass, LastModified: LastModified}'
[
    {
        "LastModified": "2014-02-21T16:26:57.000Z",
        "StorageClass": "GLACIER",
        "Key": "data/rrs.png"
    },
    {
        "LastModified": "2014-02-21T16:26:38.000Z",
        "StorageClass": "GLACIER",
        "Key": "data/std.png"
    },
    {
        "LastModified": "2014-02-21T16:26:51.000Z",
        "StorageClass": "REDUCED_REDUNDANCY",
        "Key": "rrs.png"
    },
    {
        "LastModified": "2014-02-21T16:26:21.000Z",
        "StorageClass": "STANDARD",
        "Key": "std.png"
    }
]

確かに StorageClass が GLACIER になっている。

expire 後

2日後には expiration が発生する。
プリフィックスが data/ のデータだけは S3 から削除されていることを確認。

$  aws s3api list-objects --bucket dummy-backup --query 'Contents[].{Key: Key, StorageClass: StorageClass, LastModified: LastModified}'
[
    {
        "LastModified": "2014-02-21T16:26:51.000Z",
        "StorageClass": "REDUCED_REDUNDANCY",
        "Key": "rrs.png"
    },
    {
        "LastModified": "2014-02-21T16:26:21.000Z",
        "StorageClass": "STANDARD",
        "Key": "std.png"
    }
]

Glacier からのリストア

Glacier に保存されているオブジェクトを S3 に移動させる。

リストア前

リストアされていない glacier に GET すると?

$ aws s3api head-object --bucket s3-glacier-test --key std.png
{
    "AcceptRanges": "bytes",
    "ContentType": "image/png",
    "LastModified": "Fri, 21 Feb 2014 16:05:27 GMT",
    "ContentLength": "6531",
    "ETag": "\"e14e7c238a1924ceb4bf3b557cb16319\"",
    "Expiration": "expiry-date=\"Thu, 27 Feb 2014 00:00:00 GMT\", rule-id=\"Rul e for the Entire Bucket\""
}
$ aws s3 cp s3://s3-glacier-test/std.png .
download failed: s3://s3-glacier-test/std.png to ./std.png A client error (InvalidO bjectState) occurred when calling the GetObject operation: The operation is not valid for the object's storage class

$ aws s3api head-object --bucket dummy-backup --key data/std.png
{
    "AcceptRanges": "bytes",
    "ContentType": "image/png",
    "LastModified": "Fri, 21 Feb 2014 16:26:38 GMT",
    "ContentLength": "6531",
    "ETag": "\"e14e7c238a1924ceb4bf3b557cb16319\"",
    "Expiration": "expiry-date=\"Mon, 24 Feb 2014 00:00:00 GMT\", rule-id=\"Rule for the data/ prefix\""
}

$ aws s3 cp s3://dummy-backup/data/std.png hoge.png
...
download failed: s3://dummy-backup/data/std.png to ./hoge.png A client error (InvalidObjectState) occurred when calling the GetObject operation: The operation is not valid for the object's storage class

$ aws s3api head-object --bucket s3-glacier-test --key std.png
{
    "AcceptRanges": "bytes",
    "ContentType": "image/png",
    "LastModified": "Fri, 21 Feb 2014 16:05:27 GMT",
    "ContentLength": "6531",
    "ETag": "\"e14e7c238a1924ceb4bf3b557cb16319\"",
    "Expiration": "expiry-date=\"Thu, 27 Feb 2014 00:00:00 GMT\", rule-id=\"Rule for the Entire Bucket\""
}

$ aws s3 cp s3://s3-glacier-test/std.png .
download failed: s3://s3-glacier-test/std.png to ./std.png A client error (InvalidObjectState) occurred when calling the GetObject operation: The operation is not valid for the object's storage class

リストア中

aws s3api restore-object でオブジェクトをリストアする。
3日間リストアしてみる。

$ aws s3api restore-object --bucket s3-glacier-archive --key backup/20140129/img1.jpg --restore-request Days=3
$ aws s3api head-object --bucket s3-glacier-archive --key backup/20140129/img1.jpg
{
    "Restore": "ongoing-request=\"true\"",
    "AcceptRanges": "bytes",
    "ContentType": "image/jpeg",
    "LastModified": "Tue, 28 Jan 2014 18:30:51 GMT",
    "ContentLength": "34105",
    "ETag": "\"f59f220e7de89b60ff22942ed56059c0\""
}

リストア直後は "Restore": "ongoing-request=\"true\"" となっている。
リストアが完了していないこの状態でオブジェクトを取得すると、 InvalidObjectState エラーが発生する。

$ aws s3 cp s3://s3-glacier-archive/backup/20140129/img1.jpg .
download failed: s3://s3-glacier-archive/backup/20140129/img1.jpg to ./img1.jpg A client error (InvalidObjectState) occurred when calling the GetObject operation: The operation is not valid for the object's storage class

リストア完了後

数時間待つとリストアが終了する。

$ aws s3api head-object --bucket s3-glacier-archive --key backup/20140129/img1.jpg
{
    "Restore": "ongoing-request=\"false\", expiry-date=\"Fri, 28 Feb 2014 00:00:00 GMT\"",
    "AcceptRanges": "bytes",
    "ContentType": "image/jpeg",
    "LastModified": "Tue, 28 Jan 2014 18:30:51 GMT",
    "ContentLength": "34105",
    "ETag": "\"f59f220e7de89b60ff22942ed56059c0\""
}
$ aws s3 cp s3://s3-glacier-archive/backup/20140129/img1.jpg .
download: s3://s3-glacier-archive/backup/20140129/img1.jpg to ./img1.jpg

"Restore": "ongoing-request=\"false\" となっていて、
expiry-date もリストア実行から3日後となっている。

リストア期間が終了

リストア期間が完了すると、再びストレージが S3 から Glacier に戻る。HEAD しても Restore 属性が消えている。

$ aws s3api head-object --bucket s3-glacier-archive --key backup/20140129/img1.jpg
{
    "LastModified": "Tue, 28 Jan 2014 18:30:51 GMT",
    "AcceptRanges": "bytes",
    "ETag": "\"f59f220e7de89b60ff22942ed56059c0\"",
    "ContentType": "image/jpeg",
    "ContentLength": "34105"
}

$ aws s3 cp s3://s3-glacier-archive/backup/20140129/img1.jpg .
download failed: s3://s3-glacier-archive/backup/20140129/img1.jpg to ./img1.jpg A client error (InvalidObjectState) occurred when calling the GetObject operation: The operation is not valid for the object's storage class

S3バケットをまたいだコピー

おまけとしてバケット mybucket-src のオブジェクトをバックアップ用の別バケット mybucket-target にコピーする方法。

$ aws s3 sync s3://mybucket-src/img s3://mybucket-target/img/YYYYMMDD/ --exclude *.tmp

のようにすると、バケットをまたいでコピー出来る。

mybucket-target/img 以下を Glacier にアーカイブする lifecycle を設定すると、お手軽バックアップの完成。

Advertisements
Tagged with: , , ,
Posted in aws

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archives
%d bloggers like this: