本編
はじめに
レプリケーションされたオブジェクトに対する S3 ライフサイクル動作の変更についてという記事を見て、S3 オブジェクトが残ることでコスト増加などの影響が出そうだが、それに対してどのように対処できる得るかを検討してみた。
対処方法(案)
結論
- レプリケーションの失敗の監視
- S3レプリケーションメトリクスをCloudWatch Metricに記録し、アラーム条件の設定をしてSNS経由でレプリケーションの失敗を通知
→失敗したS3 オブジェクトがあることを検知し対応可能にする
- S3レプリケーションメトリクスをCloudWatch Metricに記録し、アラーム条件の設定をしてSNS経由でレプリケーションの失敗を通知
- レプリケーション失敗の根本解決(そもそもレプリケーションが失敗しないようにするのが理想)
- S3 イベント通知により、失敗したレプリケーションのイベント通知をSNS経由で通知 or EventBridge経由でCloudWatch Logsに書き込み、でレプリケーション失敗原因の把握
→レプリケーション失敗の根本原因の解消によるレプリケーション失敗のオブジェクトを削減する
- S3 イベント通知により、失敗したレプリケーションのイベント通知をSNS経由で通知 or EventBridge経由でCloudWatch Logsに書き込み、でレプリケーション失敗原因の把握
少し詳しく
レプリケーションの失敗の監視
ポイントは以下
- S3レプリケーションメトリクスをCloudWatch Metricに配信するのは無料
- S3イベント通知を都度受け取る方法もあるがノイズになるので閾値設定で通知
- MetricのアラームでSNSを利用してファンアウト
- メールでの通知
- Slackでの通知
- AWS Chatbotは無料なのでSNSの料金のみで済む
レプリケーション失敗の根本解決
ポイントは以下
- ライブレプリケーションの場合、S3イベント通知が唯一の失敗の詳細情報を取得する手段(Batch Replicationの場合は実行結果のレポートで確認可能)
- レプリケーション失敗後にBatch Replicationで再実行し、失敗の詳細情報を取得の可能ではあるが無駄なコストがかかるのでS3イベント通知で取得するのがBest
- Slackに垂れ流しも1つの選択肢
- SNSとEventBridgeの組み合わせであれば、Lambdaの開発なしでCloudWatch Logsにレプリケーション失敗のイベントを記録可能
- CloudWatch Logsにイベントを記録することで、バランスよく分析やフィルタリングが可能(DynamoDBなどだとやり過ぎ感あるし、Slackに垂れ流しだと検索や分析しにくい)
おまけとして
S3 レプリケーション、S3 ライフサイクル、S3 Inventryなどレプリケーション失敗に関連して調べたことを備忘録として残しておく。
レプリケーション
概要
- S3 バケット間でオブジェクトを自動で非同期的にコピーする機能
- レプリケート先は、ソース(レプリケート元)と同じ・異なるリージョンどちらも可能
- レプリケート先は1つ・複数どちらも可能
- レプリケーションの種類は2つ
- ライブレプリケーション
- ルールに基づいてオブジェクトがアップロード(PUT操作)時に即座に複製
- バッチレプリケーション
- ユーザーの手動オペレーションに基づき複製
- ライブレプリケーションの設定が前提条件になる
- レプリケート対象のオブジェクトを指定するマニフェストが必要
- S3自動生成
- 既存のレプリケーション設定(プレフィックス・タグ)に基づいて自動生成
- ユーザー指定
- S3 Inventoryレポート or CSVで対象オブジェクトを指定
- S3自動生成
- バッチレプリケーションのパターンは2つ
- 新規ルール作成によるレプリケーション
- 新しいレプリケーションルール or 新しいレプリケート先を追加する際に、同時にバッチレプリケーションジョブを作成(1回限りの複製)
- 既存設定利用によるレプリケーション
- 既存のレプリケーション設定を使用してバッチレプリケーションジョブを作成
- 新規ルール作成によるレプリケーション
- ライブレプリケーション
- レプリケーションのステータス
- ライブレプリケーションでのステータス
- レプリケート元が取り得るステータス(x-amz-replication-status)
- (ヘッダーなし)=レプリケーション対象外
- FAILED
- COMPLETED
- PENDING
- レプリケート先が取り得るステータス(x-amz-replication-status)
- REPLICA
- レプリケート元が取り得るステータス(x-amz-replication-status)
- S3 Batch Replicationでの既存オブジェクトをフィルタリングする際に使用されるステータス
- NONE=一度もレプリケーションを試みたことがない
- FAILED
- COMPLETED
- REPLICA
- ライブレプリケーションでのステータス
タイミング(When)
- ライブレプリケーション
- トリガー
- オブジェクトのアップロード(PUT操作)時に即座に
- 対象
- レプリケーション設定後に作成・更新されたオブジェクトのみ
- ❌ 既存オブジェクトはレプリケーションされない
- ❌ FAILEDのステータスのオブジェクト(リトライされない)
- トリガー
- オンデマンドレプリケーション(S3 バッチレプリケーション)
- トリガー
- ユーザーが手動で実行(S3 Batch Replicationを使用)
- 対象
- レプリケーション設定前から存在していたオブジェクト
- 既存データの一括レプリケーションなどに有用
- トリガー
レプリケーション完了までの時間
- 通常のレプリケーションでも、ほとんどは15分以内にレプリケーションされる
- S3 RTC(Replication Time Control)の場合、99.99%のオブジェクトが15分以内にレプリケーションされる(SLA保証)
レプリケーション失敗の具体例
- KMS暗号化の権限不足
- シナリオ
- クロスアカウント(別のAWSアカウント間)でレプリケーションを設定し、KMS暗号化を使用している
- 問題発生の状況
- ソースバケット(アカウントA)でKMS暗号化されたオブジェクトを保存
- レプリケーション設定ではデフォルトのKMSキー(aws/s3)を使用
- デスティネーションバケット(アカウントB)は別アカウント
- どんなエラーでFAILEDになるか
- レプリケーションロールがデスティネーションアカウントのKMSキーにアクセスする権限がない
- ソースアカウントのデフォルトKMSキーを使用してしまい、デスティネーションアカウントで復号化できない
- 必要な対応
- デスティネーションバケットに複製して保存時に暗号化するためのKMSキーに関して、ポリシーでレプリケーションを実行するIAMロールにキー使用を許可
{ "Sid": "AllowS3ReplicationSourceRoleToUseTheKey", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::123456789101:role/s3-replication-role" }, "Action": ["kms:GenerateDataKey", "kms:Encrypt"], "Resource": "*" } - ソースのバケットでオブジェクトを復号するためのキー取得と、デスティネーションのバケットでオブジェクトを暗号化するためのキー取得のための許可
{ "Effect": "Allow", "Action": ["kms:Decrypt", "kms:GenerateDataKey"], "Resource": ["arn:aws:kms:region:accountA:key/source-key-id"] }, { "Effect": "Allow", "Action": ["kms:GenerateDataKey", "kms:Encrypt"], "Resource": ["arn:aws:kms:region:accountB:key/destination-key-id"] }
- デスティネーションバケットに複製して保存時に暗号化するためのKMSキーに関して、ポリシーでレプリケーションを実行するIAMロールにキー使用を許可
- シナリオ
レプリケーションメトリクス
- レプリケーションの進行状況を1分単位でモニタリング
- メトリクスの種類は以下の4つ
- 保留中のバイト数
- 保留中のオペレーション
- レプリケーションに失敗したオペレーション
- 特定のレプリケーションルールで、レプリケーションに失敗したオペレーションの数(失敗したオブジェクトの数=オペレーション失敗数)
- ex) ルールが5つで100オブジェクトをレプリケーションした時、ルールの1つで失敗が5オブジェクトなら5
- 1分間隔で集計
- 失敗した特定のオブジェクト・失敗理由を特定するには、Amazon S3 イベント通知で OperationFailedReplication イベントをサブスクライブする必要あり
- 特定のレプリケーションルールで、レプリケーションに失敗したオペレーションの数(失敗したオブジェクトの数=オペレーション失敗数)
- レプリケーションのレイテンシー
- レプリケーションの発生量に関係なくメトリクスは発行される(「オペレーション失敗レプリケーション」を除き3つに関しては)
- S3 Replication Time Control(S3 RTC)の有効化の場合、自動的にレプリケーションメトリクスも有効化される
- RTCの有効の15分後からメトリクスがレポートされる
- レプリケーション設定時に、「追加のレプリケーションオプション」でレプリケーションメトリクスの有効化をすることも可能
- 課金
- ルールごとのメトリクス4つと、レプリケーションルールの掛け算
- ex) レプリケーションルールごとの4メトリクス × 5レプリケーションルール = 20レプリケーションメトリクス
→最初の10,000のカスタムメトリクス (1メトリクスあたり0.30USD) = 20 x 0.30 = 6.00USD - APIリクエスト料金はかからない
- 通常、カスタムメトリクスをCloudWatchに送信する場合、PutMetricData APIを使用し、その呼び出し回数でAPIリクエスト料金が発生
- ただ、レプリケーションメトリクスはS3が自動的にメトリクスをCloudWatchに送信
- 送信に伴うAPIリクエスト料金は課金されない
- 不明点(ドキュメント記載なく要確認)
- レプリケーションの発生量(オブジェクト数やデータ量)に関係なく、ルール数に基づいて課金か?(レプリケーションが1日に1回でも1000回でも料金は変わらない?)
S3イベント通知でのレプリケーション失敗イベントの受信
-
S3 レプリケーションメトリクスを有効にしている場合に、S3イベント通知で以下の通知を行える
- s3:Replication:OperationFailedReplication
- レプリケーションのターゲットであったオブジェクトがレプリケートに失敗したときに通知
- s3:Replication:OperationMissedThreshold
- S3 RTC利用時に、RTCのSLAである15分の閾値を超えた
- s3:Replication:OperationReplicatedAfterThreshold
- S3 RTC利用時に、RTCのSLAである15分の閾値を超えてレプリケートされた
- s3:Replication:OperationNotTracked
- ライブレプリケーション(SRR or CRR)の対象であったオブジェクトがレプリケーションメトリクスによって追跡されなくなった
- ex) レプリケーション設定が変更され、そのオブジェクトが対象外になった
- ex) レプリケーションメトリクスの設定が変更された
- ex) オブジェクトのプレフィックスやタグがレプリケーションルールの条件から外れた
- ライブレプリケーション(SRR or CRR)の対象であったオブジェクトがレプリケーションメトリクスによって追跡されなくなった
- s3:Replication:OperationFailedReplication
- レプリケート失敗時は、このイベント通知で原因特定が可能
- S3イベント通知のデータの保存先に関して
- コスト最優先
- SNS → AWS Chatbot → Slackで、Slackに垂れ流し
- 記録としてはされるが不十分(検索しにくかったり)
- バランス
- SNS → Lambda → ClouldWatch Logs or S3 → EventBridge → CloudWatch Logs
- EventBridgeを利用するとLambdaの開発不要
- ClouldWatch Logsに記録することで、低コストで検索・分析可能
- 分析重視
- SNS → Lambda → DynamoDB
- 高速クエリ・ダッシュボード構築に分がある
- コスト最優先
- 注意事項
- ライブレプリケーションの場合、失敗の詳細理由を取得する方法はS3イベント通知のみ
- 後からAPIで理由を取得する方法はない
- Batch Replicationでは、完了レポートで確認可能(S3イベント通知に加えて)
他のサービスとの比較表
| 方法 | レプリケーション失敗検出 | 失敗理由の詳細 | リアルタイム性 | 取得方法 | コスト |
|---|---|---|---|---|---|
| S3レプリケーションメトリクス | 可能(集計値のみ) | 不可 | 1分間隔 | CloudWatch | $0.30/メトリクス/月 |
| S3イベント通知 | 可能 | 可能 | リアルタイム | SNS/SQS/Lambda | メトリクス料金 + SNS料金 |
| S3 Inventory | 可能 | 不可 | 日次/週次 | CSV/ORC/Parquet | ストレージ料金 + Athenaクエリ料金 |
| Batch Replication完了レポート | 可能 | 可能 | ジョブ実行時のみ | CSV | Batch Operations料金 |
| HeadObject API | 可能 | 不可 | リアルタイム | API呼び出し | APIリクエスト料金 |
参考文献
- レプリケーションステータス情報の取得
- リージョン内およびリージョン間でのオブジェクトのレプリケート
- Amazon S3 がレプリケートするもの
- レプリケーションのトラブルシューティング
- S3 レプリケーションメトリクスの使用
- 同じアカウントでのバケットのレプリケーションの設定
- Amazon CloudWatch 料金表
- 例 4 – S3 レプリケーションメトリクス
- Amazon S3 イベント通知によるレプリケーション失敗イベントの受信
- イベント通知のタイプおよび送信先 > SQS、SNS、および Lambda でサポートされているイベントタイプ
- バッチレプリケーションを使用した既存のオブジェクトのレプリケーション- Amazon S3 コンソールを使用したイベント通知の有効化と設定
ライフサイクル
概要
- S3ライフサイクルでコスト効率を高めることが可能
- 注意事項
- バケットポリシーでS3ライフサイクルによる移行・削除は防止不可(全てのプリンシパルのアクションをDenyに設定でも)
- 設定ルールは既存のオブジェクトとそれ以降に追加されるオブジェクトの両方に適用
- ex) 30日後に有効期限を迎え削除するルールを追加した場合、作成から30日以上経過の全てのオブジェクトが削除キューに追加される
- ライフサイクルで削除キューに追加された時点で課金は停止だが、物理的な削除は即時ではない
- ユーザーからすると課金されないのでコスト面では削除と同義)
- S3 Intelligent-Tieringへの移行の場合のみ、物理的に移行されるまでは元のストレージクラスの料金で課金
- ex) Standard → Glacier Instant Retrieval:移行対象になった時点で移行先(Glacier Instant Retrieval)の料金で課金
- ex) Standard → S3 Intelligent-Tiering:移行対象になっても移行完了までは移行元(Standard)の料金で課金
- 一部のストレージクラス(Glacier Instant Retrieval・Deep Archiveなど)では書き込み(取り込み)時にも課金される(Ingestion charge)のでコスト増に注意
- アクションの種類は2つ
- Transition actions
- 別のストレージクラスにオブジェクトを移行する
- ライフサイクル移行は別途コスト発生する
- ex) 〇日後にS3標準–IAストレージクラスにオブジェクトを移行
- 有効期限切れアクション(削除(Expiration))
- オブジェクトの有効期限を定義し、期限切れのオブジェクトの削除をする
- 1 Bucketにつき、1000ルールまで(クォータ制限の引き上げも不可)
<!-- ルールの定義のイメージは以下 --> <LifecycleConfiguration> <Rule> <!-- logs/配下で30日後に削除 --> </Rule> <Rule> <!-- images/配下で90日後にGlacierへ移行 --> </Rule> </LifecycleConfiguration>
- Transition actions
- ライフサイクルのトリガーは日付(日数)単位で、時刻はUTCの0時で固定
参考文献
S3 Inventory
概要
- バケット内の全オブジェクト・そのメタデータを定期的にレポート形式で出力するAWSマネージドサービス
- ListObjects APIのスケジュール実行の代替手段になり得てかつ、レポート生成にAPI課金されない(バケットをListObjects APIで捜索しないので)
- 標準SQLによるクエリも可能
- Athena
- Redshift Spectrum
- その他(Presto、Apache Hive、Apache Spark)
- 目的・メリット
- 大規模バケットの効率的な監査
- ex) オブジェクトのレプリケーション
- ex) 暗号化のステータス
- 大規模バケットの効率的な監査
- レポートの出力形式(以下でレポート保存先バケットに出力)
- CSV(GZIP圧縮)
- Apache ORC(ZLIB圧縮)
- Apache Parquet(Snappy圧縮)
- 頻度
- 日次
- 週次(UTC日曜日)
- ただし、初回は48時間かかる場合も
- レポートの項目(取得可能な情報)
- デフォルトフィールド(常に含まれる)
- バケット名
- オブジェクトキー
- サイズ
- 最終更新日
- ETag
- ストレージクラス
- オプションフィールド
- レプリケーションステータス
- 暗号化ステータス
- バージョンID
- オブジェクト所有者
- ...
- デフォルトフィールド(常に含まれる)
- 課金
- レポート生成
- オブジェクト数に応じた料金
- ストレージ
- 保存先バケットのストレージ料金
- クエリ
- Athenaでクエリする場合はスキャンデータ量に応じた料金
- レポート生成
- Athenaによる使用例
- ex) レプリケーション失敗の監査
SELECT key, size, last_modified_date, replication_status FROM s3_inventory WHERE replication_status = 'FAILED';
- ex) レプリケーション失敗の監査

