S3 バケットのプレフィックスごとのストレージ使用量を確認する方法をいくつか試してみた

2022.10.24

いわさです。

Amazon S3 の単一バケットを複数ユーザーで共有し、ユーザーごとにプレフィックスを分けて利用しているケースでプレフィックスごとのストレージコストを算出したいケースがあります。
Amazon S3 ではいくつかの要素から利用料金が算出されますが、本日はそのうちのストレージ利用サイズをプレフィックスごとに算出してみました。

プレフィックスごとのサイズを取得する方法はいくつか記事があったのですが、それぞれの方法をまとめて試す機会あるいは独自に計算する機会があったのでまとめておきます。

クラスメソッドメンバーズ加入アカウントでは CloudTrail や Config の出力を集約しているバケットがありますので、こちらをサンプルにプレフィックスごとに集計してみます。

1: S3 Storage Lens の高度なメトリクスとレコメンデーション機能を使う

Amazon S3 には S3 Storage Lens という機能があり、S3 の利用状況を自動で集計・分析し可視化してくれる大変便利な機能があります。

こちら基本的な機能は無料で利用出来るのですが、その場合はバケット単位での集計情報を確認することが出来ます。
ただし有償オプションの「高度なメトリクスとレコメンデーション」を有効化したダッシュボードの場合は「プレフィックス集約」という機能を使うことが出来るので、プレフィックスごとに使用状況メトリクスまで確認することが出来ます。

利用方法も簡単で、以下のようにダッシュボードの設定でメトリクスの選択オプションを設定するだけです。

設定して集計された後はダッシュボード上で以下のように「プレフィックス」タブが選択出来るようになっています。

ターゲットの S3 バケットは以下のプレフィックス構成になっていました。このプレフィックスごとに合計サイズを取得してみます。

  • バケット
    • AWSLogs
      • アカウント ID
        • CloudTrail-Digest
        • CloudTrail-Insight
        • CloudTrail
        • Config

この場合はプレフィックスの深さは「3」を指定します。
プレフィックスのしきい値は最小の 1% を指定しました。

この場合 S3 Lens ダッシュボードでは以下のように表示されました。

CloudTrail-Insight と Config はおそらくしきい値を超えなかったので集計対象外のプレフィックスとなったようです。
合計が 1.8 GB なのでだいたい 18.5 MB 以上のサイズがないプレフィックスは集計対象外となる計算です。

ちなみにプレフィックスの深さを「2」にした場合は、以下のようにひとつ上のアカウント ID のプレフィックスが最小となります。

なお、プレフィックス集約を有効化した場合はダッシュボードのフィルター機能でもプレフィックスを個別に指定することが出来ます。

なんといっても設定が楽ですし、最大 15 ヶ月分のメトリクスの推移を確認出来るのが使いやすいですね。

ただし、最新データが 1 ~ 2 日ほどタイムラグがあるのと、プレフィックスのしきい値の関係ですべてのプレフィックスが対象とならない可能性が高いので、リアルタイム性が必要だったりあるいは全てのプレフィックスの利用サイズを把握する場合には向いていなさそうです。

高い使用状況にあるバケットの特定と分析に使う用途であれば利用出来そうです。

2: マネジメントコンソールからプレフィックスを指定して集計

先程のバケットのうち Config プレフィックスのサイズがわからないままです。
マネジメントコンソールにはプレフィックスごとの合計サイズを計算して表示する機能があります。

こちらを使うと、先程 S3 Lens で確認出来なかったデータも確認することが出来ます。

こちらは自動化には向いていないですが、対象プレフィックスが少なくてその場ですぐ確認したい場合には利用が出来そうです。

3: AWS CLI でプレフィックスごとにリストした結果を集計

こうなるとやはりプレフィックスごとにオブジェクトを取得しサイズを計算することになりそうです。
実際、マネジメントコンソールでも非同期で集計しているような挙動だったので同じことをしていそうです。

今回は AWS CLI のs3api list-object-versionsを使ってみます。
しかもプレフィックスを指定するオプションも用意されていてありがたい。

s3 lsでもプレフィックスごとのオブジェクト一覧は取得出来るのですが旧バージョンなどのサイズが取得出来ないのでこちらを使ってみることにしました。

取得したオブジェクトのリストを jq で集計しました。
IsLatest でグループ化しているので現行バージョンと旧バージョンで分けて集計出来るようにしています。
ただし、厳密には削除マーカーなども計算に追加する必要があるので改良の余地がありそうです。

% aws s3api list-object-versions --bucket cm-members-123456789012 --prefix AWSLogs/123456789012/CloudTrail-Digest | jq '.Versions | group_by(.IsLatest) | map({IsLatest: .[0].IsLatest, SumByteSize: [.[].Size]|add, Count: [.[]]|length})'
[
  {
    "IsLatest": true,
    "SumByteSize": 182949987,
    "Count": 202066
  }
]

上記バケットはバージョニングが有効化されていなかったので有効化されたバケットでも試してみます。

% aws s3api list-object-versions --bucket hoge1021fuga1 --prefix piyo1 | jq '.Versions | group_by(.IsLatest) | map({IsLatest: .[0].IsLatest, SumByteSize: [.[].Size]|add, Count: [.[]]|length})'
[
  {
    "IsLatest": false,
    "SumByteSize": 20,
    "Count": 4
  },
  {
    "IsLatest": true,
    "SumByteSize": 22,
    "Count": 2
  }
]

マネジメントコンソールと比較した限りは良さそうですね。

さいごに

本日は S3 バケットのプレフィックスごとのストレージ使用量を確認する方法をいくつか試してみました。

S3 Storage Lens がお手軽で良いなと思っていたのですが、例えば単一の S3 バケットを使う複数のテナントがあってテナントプレフィックスごとに利用サイズを把握したいみたいなケースではオブジェクトから計算したほうが良さそうです。
特定のプレフィックスのみにフォーカスすれば良いようなコスト最適化のケースでは引き続き S3 Storage Lens が活躍しそうです。