海外に引っ越すにあたって、ちょっと心配だったのが手持ちのデジタルデータの保護。

今回、荷物を減らすために、持っていた本1500冊とCD500枚をすべてデジタル化して本体は処分してしまいました。(機会があればこれについても別途書く)。つまり、引っ越しの際HDDに何かあったらそれらの財産もすべてパーということ。

一応、PCのデータはネットワークストレージにもバックアップしてあるんだけど、結局PCもネットワークストレージも同じ引っ越し荷物に入るので、もし貨物まるごと紛失したり水没したりしたらバックアップの役を果たさないわけです。アメリカは荷物の扱いが雑だとも聞くし...

こういうときこそクラウドにバックアップするのがいいのでは?でも、音楽データや写真データを含む個人データとなると数百GB〜数TB級の容量が必要。そんな大容量のサービスあるの?あったとして、保険程度のバックアップのためにそこまで費用をかける価値が果たしてあるのだろうか。

...などと考えあぐねていたところに、タイミングよく AWS から Glacier というアーカイブサービスがでてました!

glacier1

ダウンロードが多少不便 (ダウンロード従量課金、ダウンロードリクエストしてから実際にダウンロードできるまで数時間待たないといけない etc.) な代わり、保管費用はひと月1GBあたり0.01ドル。つまり1TB預けても一ヶ月1000円もかからない!

その名の通り、氷河にマンモスをまるごと氷付けして、一万年ほったらかしにするような振り切ったサービス。俺の引っ越しにのために発表されたサービスと言っても過言ではないのでは!

ただ、この Glacier、ツールは何一つ用意されておらず、アップロードやダウンロードをするには自分でプログラムを組まないといけないという高いハードルがあります。
しかも、APIは基本、ファイルをひとつひとつアップロード/ダウンロードする仕様。個人ディレクトリをまるごと保存するには、いったん tar.gz で固めてからそれをアップロードすることになるので、その段階で時間が余計にかかるし、tar.gz 用にほぼ元と同じくらいの容量が必要になります。

そこで
  • 指定したディレクトリ以下をオンザフライで tar.gz 形式にして (中間ファイルを生成せずに) Glacier にアップロードできる

  • アップロードが中断しても、そこからレジューム可能

なコマンドラインツールを自前で作ったので紹介します。

いやーしかし、まさか引っ越しに java が必要だとはな...

そのうち通勤や冠婚葬祭や婚活にも java が必要になると思うのでみんなもいまのうちにやっといた方がいいですよ、java。
僕は今は ruby やってますけど。なに、scala がどうしたって?



というわけで作ったものを github にあげておきましたので、急な引っ越しの際などにどうぞ。
→ glacier-targz-uploader
...公開しといたら GUI 版が勝手につくられたりしないものかなぁ。

[glacier-targz-uploader の使い方]

1. まず AWS のマネジメントコンソールを開き、Glacier の vault を作成します。 (詳細省略)

glacier2

2. github から glacier-targz-uploader をとってきます。

2-a. ビルド済みの executable jar を builds 以下においてありますので、自前でコンパイルしなくても動くんじゃないかと思います。 (Mac OS 10.6.8 上の java 1.6.0_35 でビルド済み - executable jar ってどんな環境でもたいてい動くっけ?実行形式の java を配布するときの正しい作法がよく分かんないんだけどこれでいいのかなぁ...。もっと良い公開方法があれば教えてください。)

2-b. 自前でビルドする場合は、src/cmdline 以下にあるクラスそれぞれを、executable jar として書き出して下さい。commons-compress-1.4.1.jarcommons-cli-1.2.jar が必要になるので、あらかじめ取って来てパスを通しておく必要があります。また、ソースコードは AWS Toolkit for Eclipse が入った eclipse での作業を前提としています。

step4

以下、src/cmdline 以下の各クラスが builds ディレクトリ以下へ executable jar として書き出し済みである前提で話をすすめます。

3. AwsCredentials.properties を編集し、自分の AWS認証情報 (AWSアカウント内のセキュリティ証明書のページにあります) を書きこみます。

4. あとは、以下のような感じで executable jar を実行。

[ディレクトリを指定してアップロード]

java -Xmx1G -Dfile.encoding=UTF-8 -jar tarGzUploader.jar -dir [ディレクトリ名] -vault [vault名] -bookmark [ブックマーク名]

指定したディレクトリをオンザフライで tar.gz 形式に固めながら Glacier へアップロードします。

[ブックマーク名] には "temp" とか適当な名前をいれておけば良いです。ブックマークを指定しておくと、途中経過が同名のテンポラリファイルに書き出されます。途中でアップロードがこけたり中断したりした場合、次回全くデータ&同じブックマークを指定して起動すれば、前回の位置から resume されます。

※ -Dfile.encoding=UTF-8 を入れないと Mac OSX で日本語のファイル名が文字化けしました。tarまわりの動作が不安定に感じる場合は、以下のように純正の tar の出力を標準入出力経由で受け取る方法もあります。


[標準入力をそのままアップロード]

標準入力に入って来た内容をなんでもそのまま glacier にリダイレクトする pipedUploader というのもあるので、これに "tar -cvzf - [ディレクトリ名] - " の出力をパイプしてやっても同じことができます。

tar -cvzf - [ディレクトリ名] - | java -Xmx1G -Dfile.encoding=UTF-8 -jar pipedUploader.jar -vault [vault名] -bookmark [ブックマーク名]

アップロード終了後に Archive ID が表示されるのでそれをメモっておいて下さい。ダウンロードに必要になります。

glacier5

[ダウンロード]

ダウンロードする時はその Archive ID を指定します。

java -Xmx1G -Dfile.encoding=UTF-8 -jar downloader.jar -vault [vault名] -archive_id [アーカイブID] -out_file [出力ファイル名]

ダウンロードが開始されるまで数時間かかかります。また,アップロードした当日だとアーカイブが見つからないというエラーが返ることもあります。まあ実際にダウンロードが必要になることは稀だと思うので我慢しましょう。

[vaultの内容確認]

アーカイブIDを忘れてしまった場合は listVaultInventory.jar を使って vault にあるデータの日付、容量、アーカイブID などを確認できます。

java -Xmx1G -Dfile.encoding=UTF-8 -jar listVaultInventory.jar -vault [vault名]

ただ、このコマンドも結果が返ってくるまで数時間かかるので、Archive ID は別途メモっておくにこしたことはないです。


いずれのプログラムも、コマンド引数なしで呼び出すと簡単なヘルプを表示します。他はソース内コメント等を参照して下さい。



参考までに、これが実際の前月のAWSの請求です。この時点でアップロードしたデータは82Gほどなので、保管量自体の請求は1ドルにも満たないですね。
glacier3
ただし、このプログラムを作るためにダウンロードや listVaultInventory のテストをだいぶやったので、ダウンロードの従量課金とSQS (simple queue service) の課金も多少追加されています。
ダウンロードや vault のメタデータ取得の操作では、データが取り出し可能な状態になるまでの数時間、定期的(デフォルトでは10分おきだっけな) にSQSで問い合わせをしていて、それで細かくSQSの課金がかさみます。まあこれはプログラムの動作テストやってたからで、普通の利用形態だとほぼ無視できると思いますが。

課金上の注意点としては、

  • アップロードは基本無料だけどダウンロードは従量課金。細かくダウンロードしていると、上のSQSの料金のほかにダウンロード料金がかかる。基本はアップロードするだけと心得るべし。

  • アップロードしたデータを90日以内に削除しても,結局90日間保管したのと同じだけの早期削除料金がかかる。データは3ヶ月以上保管する前提で合計料金を見積もるべし。


といったあたりが気づいた点です。詳しくは Glacier の公式サイトで確認してください。

[追記]

Vault を削除するためには、まず vault を空にしないといけません。これが面倒なので emptyVault.jar というコマンドも追加しました。これを使えば指定の vault の中身を全て削除してくれます。(vault自体の削除はマネジメントコンソールから手動でやって下さい。)