Amazon S3のストレージ料金を無料にする裏技

追記: 無料にならなそう。後半を参照。

Amazon Simple Storage Service。 ファイル(オブジェクト)を保存したり、配信したりできるクラウドサービス。

料金は細かく設定されていて、リクエストや転送帯域に関しても課金される。 タイトルで「ストレージ料金」と言っているのは、それらを全部ひっくるめた料金ではなく、狭義の、オブジェクトを保存していることに対して毎月掛かる料金。 最も安いS3 Glacier Deep Archiveでも、0.002USD/GB/月(東京リージョン、2022年1月現在)掛かる。 一見とても安く思えるが、例えば100 TBを10年保存しようと思うと、24,576ドル、約300万円にもなってしまう。 オブジェクトを保存したり取り出したりするときに金が掛かるのは諦めるとして、この保存に掛かる料金を無料にしたい。

はい。

f:id:kusano_k:20220126231820p:plain

ファイルサイズが0バイトなので、お金は掛からないはずである。

f:id:kusano_k:20220126232039p:plain

元のファイルの中身を分割してファイル名にしている。 手元のストレージで同じ事をすると、一見ファイルサイズが0に見えて、inode(ext4)やMFT(NTFS)の容量を消費するから、当然無限に保存できるわけではない。

オブジェクトを1個保存するたびにリクエスト料金が掛かるため、多数のオブジェクトに分割することによって、最初の保存時の料金が高くなる。 何年保存すれば得になるのか、損益分岐点を計算してみる。

素直にファイルをそのままオブジェクトとして保存したときは、最安で0.002USD/GB/月。

キー名(オブジェクト名)は、最大UTF-8で1024バイト。

オブジェクトキー名の作成 - Amazon Simple Storage Service

UTF-8として無効なキー名も使えないかな?」と思ったけど、少なくともAWS CLIでは弾かれた。 バイト列をUTF-8として有効なUnicodeに変換したときにどの程度の詰め込めるかに興味はあるものの……まあ、Base64で良いだろ。 Base64ではサイズが4/3倍に増える。 (コントロールパネルからはディレクトリっぽく見えるけど)S3のキー名にディレクトリの概念は無い。 元のファイル名と連番の部分で32バイト程度は使うだろうか。 1個のオブジェクトのキー名に、(1024-32)/(4/3)で744バイト分のデータを詰め込める。

ファイルの取り出しのLISTは1000件まとめて取得できるので、無視できる。 PUTリクエストは0.0047USD/1,000回。 1回、1バイトあたり6.3172×10-9USD。 ストレージ料金の「GB」が10003なのか10243なのか分からない。 10243とすると、6.783USD/GB。 ということで、3,392月=283年以上保存するならば、S3 Glacier Deep Archiveに保存するよりも、ファイル名にエンコードしたほうがお得💰💰💰


当然「本当に無料になるの?」というのが気になる。 料金の算出の元になるであろうバケットの合計サイズは「バケットメトリクス」で確認でき、これは1日1回更新される。 1日以上経ったので確認してみた。 オブジェクト数717個で、バケットサイズ0バイトになっていれば良い。

f:id:kusano_k:20220129002439p:plain

727.7 KB。 ダメそう😢

なぜファイルサイズが0バイトなのにバケットのサイズが増えているんだという話だが……。

メタデータもストレージ使用量の課金対象

kurochan-note.hatenablog.jp

ここで挙げられているメタデータだけで、1ファイル1 KBにはならないだろうし、ファイル名もメタデータ扱いなのかなぁ。

CloudWatchだとバイト単位の正確な値が確認できて、745,129バイト。 キー名の合計は733,657文字。 キー名の分を除くと、11,472バイト。 オブジェクト1個あたりちょうど16バイト。 切りが良いので、計算は合っていそう。

この16バイトが何なのかは謎。 ETagなのか。 あるいは、(特に設定していない)Content-Typeは text/plain の10文字だったから、それと LastModified か何かで6バイトなのか。