S3イベント通知 vs EventBridge 処理漏れ率を比べてみた

2020.03.30

S3バケットにファイルがアップロードされたのを起点に何かしらの処理を実行する、というのはAWSにおけるよくある(?)アーキテクチャです。例としてよく挙げられるのは以下のような、画像ファイルをアップロードしたらそのサムネイル画像を作成する処理です。

S3イベント通知

この際に使うのがS3イベント通知機能です。S3に関する様々なイベントが発生した場合に他のAWSサービスを起動させることができます。例えば上記サムネイル画像を作成する場合だと、ObjectCreate (All) のイベントでLambda関数を実行しています。

ですがこのS3イベント通知、時たま処理漏れすることがある、と言われています。そのため漏れが許容できない場合は、以下例の様に処理漏れしているファイルを検知して処理再実行する機構を用意するなどの措置が必要になります。

EventBridge(CloudWatch Events)

実はEventBridge(CloudWatch Events)でも上記のようなS3へのファイルアップロードを起点に他のAWSサービスを起動させることができます。EventBridgeは様々なAWSサービスのイベントをトリガに、ターゲット(Lambda関数など)の処理を実行することができるサービスです。以下にトリガーとなるイベントの一覧があります。

この一覧にはS3が含まれていません。S3イベントの場合、CloudTrailでバケットのオブジェクトレベルの認証を有効化し、そのCloudTrailイベントをEventBridgeで拾うことでイベント検知→ターゲット処理実行とすることができます。

本題: S3イベント通知 / EventBridge どちらのほうが処理漏れが少ないのか?

前述の通り、S3イベント通知は処理漏れすることがある、と言われています。ではEventBridge(CloudTrail→EventBridge)の方はどうなんだろう?処理漏れ少なそうなイメージはあるけど…と疑問に思ったので検証してみることにしました。

検証内容

同一S3バケットに対して2つの処理系統を用意します。

  • S3バケット → S3イベント通知 → SNSトピック
  • S3バケット → CloudTrailオブジェクトレベル認証 → EventBridge → (上記処理で使っているのとは別の)SNSトピック

このS3バケットに対して、オブジェクトを10,000個作成します。 SNSトピックのCloudWatchメトリクスNumberOfMessagesPublishedにて発行されたメッセージ数が確認可能です。 処理漏れが無ければ、どちらの処理系統のメトリクス値も10,000になるはずです。 双方どの程度処理漏れが発生するのか検証してみます。

オブジェクト10,000個の作成は以下のようなTerraformのコードで行ないました。

resource null_resource put-s3-objects {
  count = 10000
  provisioner local-exec {
    command = "aws s3api put-object --bucket ${data.aws_s3_bucket.main.bucket} --key 10000/file${count.index}.txt"
  }
}

10,000個一斉に作成されるのではなく、徐々に作成されていきます。TF_CLI_ARGS_apply="-parallelism=50"としていたので、約50個のオブジェクト作成が並列で実行されていたようです。

検証結果

S3イベント通知とEventBridge、両方のメトリクス値とも 10,000になりました。

…すみません、10,000回程度ではどちらも処理漏れは発生しませんでした。
もっともっとオブジェクトを作成していけば差が出てくるのかもしれませんが、オブジェクト作成に時間がかかるので今回はここまでとします。

ドキュメントにはどの様に書いてあるのか

S3イベント通知機能

Amazon S3 イベント通知の設定 | S3 開発者ガイド

処理漏れに関する記述は以下くらいしか見つけらませんでした。

バージョン管理されていない単一のオブジェクトに同時に 2 つの書き込みを行うと、イベント通知が 1 つしか送信されない場合があります。バケットのバージョニングを有効にすると、正常な書き込みごとにイベント通知を受信できます。バージョニングでは、正常な書き込みごとにオブジェクトの新しいバージョンが作成され、イベント通知が送信されます。

今回は「単一のオブジェクトに同時に 2 つの書き込み」を行なっていませんので、関係のない記述です。

Amazon S3 オブジェクトに対してイベント通知がトリガーされたかどうかを確認する方法を教えてください。| AWS ナレッジセンター

通常、Amazon S3 イベント通知は数秒でイベントを配信しますが、時間がかかる場合もあります。ごくまれに、イベントが失われることもあります。

EventBridge

ターゲットへのイベントの配信で遅延が発生した | EventBridgeユーザーガイド トラブルシューティング

EventBridge は、最大 24 時間にわたりターゲットにイベントを配信しようとします。最初の試行は、イベントがイベントストリームに到達するとすぐに行われます。ただし、ターゲットサービスに問題がある場合、EventBridge は自動的に別の配信を再スケジュールします。イベントの到着から 24 時間が経過すると、それ以上の試行はスケジュールされず、FailedInvocations メトリクスが CloudWatch で発行されます。FailedInvocations メトリクスに基づいて CloudWatch アラームを作成することをお勧めします。

これを読むと、EventBridgeの方が処理漏れが少なそうに見えますね。

まとめ

  • S3バケットにオブジェクトがアップロードされたことを起点になにかしらの処理を実行したい場合、その方法がふたつ存在する。S3イベント通知機能とEventBridge。
  • 両者の処理漏れ率を比べたが、10,000件のオブジェクト作成ではどちらも処理漏れが発生しなかった。

つづき

後日ファイル数を増やして再挑戦しました。