最小オブジェクトサイズより小さなオブジェクトを格納した際にストレージ料金はどのように課金されるのか

S3 Glacier Instant Retrieval で 128 KB 未満のオブジェクトを格納すると、不足分が別の請求項目として請求されます。

「適切なストレージクラス料金」とは何を指すのか

コンバンハ、千葉(幸)です。

S3 バケットに格納するオブジェクトにはストレージクラスを設定でき、それによってストレージ料金が変わります。そして一部のストレージクラスでは最小オブジェクトサイズという考え方があります。

S3 Glacier Instant Retrieval ストレージクラスを例にとると、S3 料金ページで以下の記述がされています。 *1

S3 Glacier Instant Retrieval has a minimum billable object size of 128 KB. Smaller objects may be stored but will be charged for 128 KB of storage at the appropriate storage class rate.

(日本語版)

S3 Glacier Instant Retrieval の課金対象となる最小オブジェクトサイズは 128 KB です。128 KB より小さいサイズのオブジェクトを保存することもできますが、適切なストレージクラス料金で 128 KB のストレージとして課金されます。

.oO(「適切なストレージクラス料金」とは……?)


この記述を読んだ時、皆さんはどちらの意味で受け取ったでしょうか。

  • 128 KB より小さいオブジェクトは 128 KB として S3 Glacier Instant Retrieval のストレージ料金で課金される
  • 128 KB より小さいオブジェクトは 128 KB として別のストレージクラスのストレージ料金で課金される

わたしは初見では後者の意味で捉えたのですが、実際どうなのだろうということが気になったので試してみました。

まとめ

  • 最小オブジェクトサイズより小さなオブジェクトを格納した場合、差分を埋めるようにストレージ料金が課金される
  • 差分のストレージ料金は請求ダッシュボード上では別の項目として計上される
  • オブジェクトそのもの、および差分のストレージ料金は同じストレージクラスで課金される

(なお、上記の考え方は「最小オブジェクトサイズが 128 KB のストレージクラス」の前提で書いています。)

ということで、冒頭の例で考えると「128 KB より小さいオブジェクトは 128 KB として S3 Glacier Instant Retrieval のストレージ料金で課金される」が正しい考え方でした。

最小オブジェクトサイズより小さいオブジェクト格納してみた

今回は以下の方式で挙動を確認してみました。

  • 普段利用していないリージョンで S3 バケットを作成し、様々なサイズのオブジェクトを格納する
  • 一定期間おいて、請求ダッシュボード上でどのように課金されているかを確認する

ひとまずサンプルは多いほうがいいだろう、ということで以下の組み合わせで試してみます。

リージョン名 リージョン ストレージクラス オブジェクトサイズ
オハイオ us-east-2 GLACIER_IR 1KB
ムンバイ ap-south-1 GLACIER_IR 8KB
シンガポール ap-southeast-1 GLACIER_IR 32KB
シドニー ap-southeast-2 GLACIER_IR 127KB
アイルランド eu-west-1 GLACIER_IR 128KB
ロンドン eu-west-2 GLACIER_IR 256KB
パリ eu-west-3 STANDARD_IA 32KB
ストックホルム eu-north-1 ONEZONE_IA 32KB

表中の「ストレージクラス」は以下を表します。いずれも 128KB が最小オブジェクトサイズであるストレージクラスです。

  • GLACIER_IR:S3 Glacier Instant Retrieval
  • STANDARD_IA:S3 標準 - 低頻度アクセス
  • ONEZONE_IA:S3`1 ゾーン - 低頻度アクセス

今回試行する前の請求ダッシュボードの S3 の項目はこんな感じ。上記の表のリージョンはいずれも料金が発生していない状態です。

S3_Glacier_cost

さまざまなサイズのファイルを作成する

以下のページを参考に、各種サイズのファイルを作成します。

dd if=/dev/zero of=1kb.test bs=1K count=1
dd if=/dev/zero of=8kb.test bs=1K count=8
dd if=/dev/zero of=32kb.test bs=1K count=32
dd if=/dev/zero of=127kb.test bs=1K count=127
dd if=/dev/zero of=128kb.test bs=1K count=128
dd if=/dev/zero of=256kb.test bs=1K count=256

それぞれ想定通りのサイズのファイルが作成できました。

% ls -goh | grep kb.test
-rw-r--r--   1    127K 12 13 18:44 127kb.test
-rw-r--r--   1    128K 12 13 18:45 128kb.test
-rw-r--r--   1    1.0K 12 13 18:43 1kb.test
-rw-r--r--   1    256K 12 13 18:45 256kb.test
-rw-r--r--   1     32K 12 13 18:44 32kb.test
-rw-r--r--   1    8.0K 12 13 18:44 8kb.test

さまざまなサイズのファイルを各リージョンの S3 バケットに格納していく

あらかじめ各リージョンにchibayuki-test-{リージョン名}という名称で S3 バケットを作成済みです。それらに対してストレージクラスを指定してファイルを Put していきます。

例えばオハイオリージョンの S3 バケットに格納する場合はこんな感じ。

% aws s3api put-object\
    --bucket chibayuki-test-us-east-2\
    --key 1kb.test\
    --body 1kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"0f343b0931126a20f133d67c2b018a3b\""
}

格納されたオブジェクトを確認すると、指定した通りのストレージクラスになっています。

S3_Glacier_IR_cost

残りのファイルも順次 Put します。

% aws s3api put-object\
    --bucket chibayuki-test-ap-south-1\
    --key 8kb.test\
    --body 8kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"0829f71740aab1ab98b33eae21dee122\""
}

% aws s3api put-object\
    --bucket chibayuki-test-ap-southeast-1\
    --key 32kb.test\
    --body 32kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"bb7df04e1b0a2570657527a7e108ae23\""
}

% aws s3api put-object\
    --bucket chibayuki-test-ap-southeast-2\
    --key 127kb.test\
    --body 127kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"f9b5ef697fde92c42bbbec35e5a6cad4\""
}

% aws s3api put-object\
    --bucket chibayuki-test-eu-west-1\
    --key 128kb.test\
    --body 128kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"0dfbe8aa4c20b52e1b8bf3cb6cbdf193\""
}

% aws s3api put-object\
    --bucket chibayuki-test-eu-west-2\
    --key 256kb.test\
    --body 256kb.test\
    --storage-class GLACIER_IR
{
    "ETag": "\"ec87a838931d4d5d2e94a04644788a55\""
}

GLACIER_IR以外のストーレジクラスも Put します。

% aws s3api put-object\
    --bucket chibayuki-test-eu-west-3\
    --key 32kb.test\
    --body 32kb.test\
    --storage-class STANDARD_IA
{
    "ETag": "\"bb7df04e1b0a2570657527a7e108ae23\""
}

% aws s3api put-object\
    --bucket chibayuki-test-eu-north-1\
    --key 32kb.test\
    --body 32kb.test\
    --storage-class ONEZONE_IA
{
    "ETag": "\"bb7df04e1b0a2570657527a7e108ae23\""
}

翌日に請求ダッシュボードを覗いてみる

一晩あけて請求ダッシュボードを覗いてみます。リクエスト料金は反映されているもののストレージ料金が表れていません。まだ早かったようです。もう少し寝かせてみましょう。

Glacier_cost

.oO(料金種別によって請求ダッシュボードに反映されるタイミングがズレるんだな、ということと、あまり意識してなくてもリクエストの回数が発生しているんだな、ということを学びました。)

一週間ほど寝かせて請求ダッシュボードを覗いてみる

十分な時間を置いて改めて請求ダッシュボードを覗いてみます。ストレージ料金が反映されており、通常のストレージ料金と小さなオブジェクト用のストレージ料金が分かれていることが読み取れます。

Billing_Management_Console_Glacier_cost

32 KB のファイルを格納したパリリージョンを例にとると、以下の数字になっています。

  • $0.0131 per GB-Month of storage used in Standard-Infrequent Access:0.000006 GB-Mo
  • $0.0131 per GB-Month of storage used for small objects:0.000018 GB-Mo

1GB = 1,000,000 KB、1 Month = 720 時間 で考えると、135 時間分の料金で計上されていそうです。また、両者の比率が 1:3 になっているため、32 KB : 96 KB であり、合計して 128 KB になるように計算されているように読み取れます。

この調子で各リージョンの内訳を確認すると以下のようになっていました。

リージョン ストレージクラス オブジェクトサイズ ByteHrs (GB-Mo) SmObjects(GB-Mo) 比率 備考
us-east-2 GLACIER_IR 1KB 0.00000018 0.000023 127.78 1KB:127.78KB
ap-south-1 GLACIER_IR 8KB 0.000002 0.000022 11 8KB:88KB?
ap-southeast-1 GLACIER_IR 32KB 0.000006 0.000018 3 32KB:96KB
ap-southeast-2 GLACIER_IR 127KB 0.000023 0.00000018 0.0078 127KB:1KB
eu-west-1 GLACIER_IR 128KB 0.000024 - -
eu-west-2 GLACIER_IR 256KB 0.000047 - -
eu-west-3 STANDARD_IA 32KB 0.000006 0.000018 3 32KB:96KB
eu-north-1 ONEZONE_IA 32KB 0.000006 0.000018 3 32KB:96KB

完全に綺麗に数字が出たわけではないですが、

  • オブジェクトサイズに応じた料金が発生する
  • 最小オブジェクトサイズに満たない場合、その差分を埋めるように料金が発生する

ということが分かりました。

最小オブジェクトサイズに満たないオブジェクトはライフサイクルで移行されない

ここまで見てきたような「最小オブジェクトサイズ未満のオブジェクトを格納したとき」の挙動について、意識する機会は少ないかもしれません。

というのも今回取り上げたストレージクラスは、 128 KB 未満の場合はライフサイクルによるストレージクラス移行の対象外となるためです。

  • Objects smaller than 128 KB – For the following transitions, Amazon S3 does not transition objects that are smaller than 128 KB:
    • From the S3 Standard or S3 Standard-IA storage classes to S3 Intelligent-Tiering or S3 Glacier Instant Retrieval.
    • From the S3 Standard storage class to S3 Standard-IA or S3 One Zone-IA.

Put 時に明示的にストレージクラスを指定した時のみ、「最小オブジェクトサイズより小さいオブジェクトを格納」が実現できます。多くの場合はライフサイクルによるストレージクラス移行が採用されるかと思いますので、機会が少ないのではと考えています。

最小オブジェクトサイズが 40 KB のものもある

ここまでは 128 KB が最小オブジェクトサイズのストレージクラス 3 つのみを取り上げてきましたが、他にも最小オブジェクトサイズが設けられているストレージクラスがあります。

S3 Glacier Flexible Retrieval、S3 Glacier Deep Archive は最小オブジェクトが 40 KB です。これらについては最小オブジェクトサイズが 128 KB のものとは考え方が異なりそうです。

S3 Glacier Flexible Retrieval または S3 Glacier Deep Archive に保存されている各オブジェクトの場合、Amazon S3 はメタデータに対する課金可能な 40 KB のオーバーヘッドを追加し、それは、S3 標準レートで請求される 8 KB と S3 Glacier Flexible Retrieval または S3 Deep Archive レートで請求される 32 KB から構成されます。

(料金ページより)

オブジェクトごとに 40KB のメタデータが追加されるため、それをもって「最小オブジェクトサイズ40 KB」とされているようです。

終わりに

最小オブジェクトサイズより小さなオブジェクトを格納した際にストレージ料金はどのように課金されるのか、を確認してみました。(正確に言うと「最小オブジェクトサイズが 128 KBのストレージクラスについて、〜」の接頭辞がつきますね。)

「適切なストレージクラス」という言葉の解釈に迷ってしまいましたが、要は差分を埋めるようにストレージ料金が発生する、ということでした。そしてその差分は請求の項目としては別で表される、というのが新鮮な気づきでした。

細かいことが気になった方の参考になれば幸いです。

以上、 チバユキ (@batchicchi) がお送りしました。

参考

脚注

  1. 同様の記述は S3 Standard-IA と S3 One Zone-IA にもあります。