1
0

More than 1 year has passed since last update.

Glacierに保存したオブジェクトをまとめて復元するシェルスクリプト

Posted at

はじめに

Amazon S3にはストレージクラスと呼ばれる、データの保管料金を節約する機能があります。
主に利用頻度の少ないデータを保管する際に使う機能となり、データの取り出しかかる時間や費用の増加、可用性が低下などを許容する代わりに、データ保管にかかる料金を節約できます。
つまり、S3に保存されているオブジェクトの使用頻度や可用性に合わせてストレージクラスを変更させることで日々のS3の利用料金を抑えることが可能となります。
そして、ストレージクラスの一つがGlacierとなります。

このGlacier、保存されているオブジェクトは一度復元というステップを踏まないとデータを取り出すことができません。
この特徴のため、今回S3のオブジェクトを別アカウントのS3に移動させようとしてs3 syncコマンドを実行したところ以下のようなエラーが発生しました。

Object is of storage class GLACIER. Unable to perform copy operations on GLACIER objects. You must restore the object to be able to perform the operation. See aws s3 copy help for additional parameter options to ignore or force these transfers.

そのため、オブジェクトを復元してからsyncコマンドを実行すればいいだけの話なのですが、復元はオブジェクトごとにしか実行することができず、大量のオブジェクトがあるバケットに対して復元を実行しようとする場合、数千/数万回マウスをカチカチしなければならなくなります。

そこで今回はAWS CLIをインストールしたMacOSで実行/放置しておくだけで、勝手にGlacierに保管されているオブジェクトを復元してくれるシェルスクリプトを作成してみました。

シェルスクリプトファイルの中身

restore_glacier_objects.sh

#!/bin/bash
​
bucket=$1
prefix=$2
​
aws s3api list-objects --bucket $bucket --prefix "$prefix" --query "Contents[?StorageClass=='GLACIER'].[Key]" --output text | while read object; do
  echo "Restoring object $object from $bucket"
  aws s3api restore-object --bucket $bucket --key "$object" --restore-request '{"Days":3,"GlacierJobParameters":{"Tier":"Bulk"}}'
done

実行時のコマンド
シェルスクリプトを保存したディレクトリへ移動し、以下を実行
sh restore_glacier_objects.sh <バケット名> <プレフィックス>


バケット名:s3-test
プレフィックス:s3://s3-test/page1/
とした場合

sh restore_glacier_objects.sh s3-test page1/

仕様の解説

  • 変数としてバケット名とプレフィックス(パスみたいなもの)を与える
  • AWS CLIのs3api list-objectsを使用してストレージクラスがGlacierのオブジェクトを抽出
  • 抽出したオブジェクトなくなるまで、1つずつループで復元
  • 復元されている期間は3日
  • 大容量取り出し(Bulk)を使用することで取り出しにかかる費用を抑える

注意点

AWS CloudShellでの大量オブジェクトの復元は非推奨です。

というのもAWS CloudShellには以下のような制約があります。

・非アクティブセッション:AWS CloudShellは対話型のシェル環境であり、20~30 分にわたってキーボードとポインタを使った操作がない場合、シェルセッションは終了します。実行中のプロセスは、操作数としてカウントされません。
・実行時間が長いセッション:約 12 時間連続して実行されているシェルセッションは、ユーザーがその期間に定期的に操作している場合でも、自動的に終了します。

また、コンピューティング能力も高くないため、大量のオブジェクトを復元しようとすると時間がかかってしまいます。
そのため、プレフィックスをうまく切ってシェルスクリプトを実行したり、定期的にAWS CloudShellの画面で何かしらのキーを叩く(Automatorを使ってもいい?)必要があり、シェルスクリプトを作ったとしても結構大変なので、AWS CloudShellではなく、ローカルにAWS CLIをインストールしてシェルスクリプトをを実行する方がいいかと思います。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0