Amazon SQS での Lambda の使用
注記
Lambda 関数以外のターゲットにデータを送信したい、または送信する前にデータをエンリッチしたいという場合は、「Amazon EventBridge Pipes」を参照してください。
Amazon Simple Queue Service (Amazon SQS) キュー内のメッセージを処理するには、Lambda 関数を使用することができます。Lambda は、イベントソースマッピングで、標準キューとファーストイン、ファーストアウト (FIFO) キューの両方をサポートしています。プロビジョンドモードを使用して、Amazon SQS イベントソースマッピング専用のポーリングリソースを割り当てることもできます。Lambda 関数と Amazon SQS キューは同じ AWS リージョンに存在する必要がありますが、異なる AWS アカウントにすることができます。
Amazon SQS メッセージを処理するときは、部分的なバッチレスポンスロジックを実装して、バッチ内の一部のメッセージが失敗した場合に正常に処理されたメッセージが再試行されないようにする必要があります。Powertools for AWS Lambda のバッチプロセッサユーティリティ
トピック
Amazon SQS イベントソースマッピングのポーリングとバッチ処理の動作を理解する
Amazon SQS イベントソースマッピングでは、Lambda はキューをポーリングし、イベントと共に関数を同期的に呼び出します。各イベントには、キューからの複数のメッセージのバッチを含めることができます。Lambda は、これらのイベントをバッチとして (一度に 1 バッチずつ) 受け取り、バッチごとに関数を 1 回呼び出します。関数が正常にバッチを処理すると、Lambda はキューからそのメッセージを削除します。
Lambda がバッチを受け取ると、メッセージはキューに留まりますが、キューの可視性タイムアウトの期間中は非表示になります。関数がバッチ内のすべてのメッセージを正常に処理すると、Lambda はそのメッセージをキューから削除します。デフォルトでは、バッチの処理中に関数でエラーが発生すると、可視性タイムアウトの期限が切れた後に、そのバッチ内のすべてのメッセージが再びキューに表示されます。このため、関数コードは、意図しない副次的影響を及ぼすことなく同じメッセージを複数回処理できるようにする必要があります。
警告
Lambda イベントソースマッピングは各イベントを少なくとも 1 回処理し、レコードの重複処理が発生する可能性があります。重複するイベントに関連する潜在的な問題を避けるため、関数コードを冪等にすることを強くお勧めします。詳細については、AWS ナレッジセンターの「Lambda 関数を冪等にするにはどうすればよいですか?
Lambda がメッセージを複数回処理しないようにするには、関数レスポンスにバッチアイテムの失敗を含めるようにイベントソースマッピングを設定するか、DeleteMessage API を使用して、Lambda 関数がメッセージを正常に処理した場合にそれらをキューから削除することができます。
Lambda が SQS イベントソースマッピングでサポートする設定パラメータの詳細については、「SQS イベントソースマッピングの作成」を参照してください。
Amazon SQS イベントソースマッピングでのプロビジョンドモードの使用
イベントソースマッピングのスループットを微調整する必要があるワークロードでは、プロビジョンドモードを使用できます。プロビジョンドモードでは、プロビジョニングされたイベントポーラーの最小数と最大数を定義します。これらのプロビジョニングされたイベントポーラーは、イベントソースマッピング専用であり、応答性の高い自動スケーリングによって予期しないメッセージスパイクを処理できます。プロビジョンドモードで設定された Amazon SQS イベントソースマッピングは、デフォルトの Amazon SQS イベントソースマッピング機能よりも 3 倍高速 (1 分あたり最大 1,000 回の同時呼び出し) に動作し、16 倍高い同時実行 (最大 20,000 回の同時呼び出し) をサポートします。マーケットデータフィードを処理する金融サービス会社、リアルタイムのパーソナライズされたレコメンデーションを提供する e コマースプラットフォーム、ライブプレイヤーインタラクションを管理するゲーム会社など、高精度なパフォーマンス要件を持つ Amazon SQS イベント駆動型ワークロードには、プロビジョンドモードを使用することをお勧めします。プロビジョニングモードを使用すると、追加コストが発生します。料金の詳細については、「AWS Lambda の料金
プロビジョンドモードの各イベントポーラーは、最大 1 MB/秒のスループット、最大 10 回の同時呼び出し、または 1 秒あたり最大 10 回の Amazon SQS ポーリング API コールを処理できます。イベントポーラーの最小数 (MinimumPollers) の許容値の範囲は 2~200 で、デフォルトは 2 です。イベントポーラーの最大数 (MaximumPollers) の許容値の範囲は 2~2,000 で、デフォルトは 200 です。MaximumPollers は MinimumPollers より大きな数でなければなりません。
必要なイベントポーラーの決定
SQS ESM にプロビジョンドモードを使用するときに最適なメッセージ処理パフォーマンスを確保するために必要なイベントポーラーの数を推定するには、アプリケーションの次のメトリクスを収集します。低レイテンシー処理を必要とする 1 秒あたりのピーク SQS イベント、平均 SQS イベントペイロードサイズ、平均 Lambda 関数期間、および設定されたバッチサイズ。
まず、次の式を使用して、ワークロードのイベントポーラーでサポートされている SQS イベント/秒 (EPS) の数を見積もることができます。
EPS per event poller = minimum( ceiling(1024 / average event size in KB), ceiling(10 / average function duration in seconds) * batch size, min(100, 10 * batch size) )
次に、以下の式を使用して、必要な最小ポーラーの数を計算できます。この計算により、ピークトラフィック要件を処理するのに十分な容量をプロビジョニングできます。
Required event pollers = (Peak number of events per second in Queue) / EPS per event poller
デフォルトのバッチサイズが 10、平均イベントサイズが 3 KB、平均関数期間が 100 ミリ秒、1 秒あたり 1,000 イベントを処理する必要があるワークロードを考えてみましょう。このシナリオでは、各イベントポーラーは 1 秒あたり約 100 イベント (EPS) をサポートします。したがって、ピークトラフィック要件を適切に処理するには、最小ポーラーを 10 に設定する必要があります。ワークロードの特性は同じですが、平均関数時間が 1 秒の場合、各ポーラーは 10 回の EPS のみをサポートするため、低レイテンシーで 1 秒あたり 1,000 イベントをサポートするように 100 回の最小ポーラーを設定する必要があります。
プロビジョンドモードイベントポーラーの効率を最大化するには、デフォルトのバッチサイズ 10 かそれ以上を使用することをお勧めします。バッチサイズを大きくすると、各ポーラーは呼び出しごとにより多くのイベントを処理することができ、スループットとコスト効率が向上します。イベントポーラー容量を計画するときは、トラフィックの急増の可能性を考慮し、バッファを持たせるために minimumPollers 値を計算された最小値よりわずかに高く設定することを検討してください。さらに、最適なパフォーマンスとコスト効率を維持するために、メッセージサイズ、関数の期間、またはトラフィックパターンの変更によりイベントポーラー設定の調整が必要になる場合があるため、ワークロードの特性を経時的にモニタリングします。正確なキャパシティプランニングを行うには、特定のワークロードをテストして、各イベントポーラーが駆動できる実際の EPS を決定することをお勧めします。
Amazon SQS イベントソースマッピングのプロビジョンドモードを設定する
Amazon SQS イベントソースマッピングのプロビジョンドモードを設定するには、コンソールまたは Lambda API を使用できます。
既存の Amazon SQS イベントソースマッピングに対してプロビジョンドモードを設定する手順 (コンソール)
-
Lambda コンソールの [関数]
ページを開きます。 -
プロビジョンドモードを設定する Amazon SQS イベントソースマッピングを持つ関数を選択します。
-
[設定] タブを選択し、[トリガー] を選択します。
-
プロビジョンドモードを設定する Amazon SQS イベントソースマッピングを選択し、[編集] をクリックします。
-
[イベントソースマッピング設定] で、[プロビジョンドモードの設定] を選択します。
-
[最小イベントポーラー数] に、2~200 の値を入力します。値を指定しない場合、Lambda はデフォルト値 2 を選択します。
-
[最大イベントポーラー数] に、2~2,000 の値を入力します。この値は、[最小イベントポーラー数] の値以上である必要があります。値を指定しない場合、Lambda はデフォルト値 200 を選択します。
-
-
[保存] を選択します。
プロビジョンドモードは、EventSourceMappingConfiguration の ProvisionedPollerConfig オブジェクトを使用してプログラムで設定できます。例えば、次の UpdateEventSourceMapping CLI コマンドは、MinimumPollers 値を 5、MaximumPollers 値を 100 に設定します。
aws lambda update-event-source-mapping \ --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \ --provisioned-poller-config '{"MinimumPollers": 5, "MaximumPollers": 100}'
プロビジョニングモードを設定すると、ProvisionedPollers メトリクスをモニタリングすることで、ワークロードのイベントポーラーの使用状況を確認できます。詳細については、「イベントソースマッピングメトリクス」を参照してください。
プロビジョンドモードを無効にしてデフォルト (オンデマンド) モードに戻すには、次の UpdateEventSourceMapping CLI コマンドを使用できます。
aws lambda update-event-source-mapping \ --uuid a1b2c3d4-5678-90ab-cdef-EXAMPLE11111 \ --provisioned-poller-config '{}'
注記
プロビジョンドモードは、最大同時実行数設定と組み合わせて使用することはできません。プロビジョンドモードを使用する場合、イベントポーラーの最大数を通じて最大同時実行数を制御します。
プロビジョンドモードの設定の詳細については、「Amazon SQS イベントソースマッピングの作成と管理」を参照してください。
標準キューメッセージイベントの例
例 Amazon SQS メッセージイベント (標準キュー)
{ "Records": [ { "messageId": "059f36b4-87a3-44ab-83d2-661975830a7d", "receiptHandle": "AQEBwJnKyrHigUMZj6rYigCgxlaS3SLy0a...", "body": "Test message.", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1545082649183", "SenderId": "AIDAIENQZJOLO23YVJ4VO", "ApproximateFirstReceiveTimestamp": "1545082649185" }, "messageAttributes": { "myAttribute": { "stringValue": "myValue", "stringListValues": [], "binaryListValues": [], "dataType": "String" } }, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "awsRegion": "us-east-2" }, { "messageId": "2e1424d4-f796-459a-8184-9c92662be6da", "receiptHandle": "AQEBzWwaftRI0KuVm4tP+/7q1rGgNqicHq...", "body": "Test message.", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1545082650636", "SenderId": "AIDAIENQZJOLO23YVJ4VO", "ApproximateFirstReceiveTimestamp": "1545082650649" }, "messageAttributes": {}, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:my-queue", "awsRegion": "us-east-2" } ] }
デフォルトでは、Lambda はキュー内の最大 10 個のメッセージを一度にポーリングし、そのバッチを関数に送信します。少数のレコードで関数が呼び出されることを回避するには、バッチウィンドウを設定することで、最大 5 分間レコードをバッファリングするようにイベントソースに指示できます。関数を呼び出す前に、Lambda は、バッチ処理ウィンドウの期限が切れる、呼び出しペイロードサイズのクォータに到達する、または設定された最大バッチサイズに到達するまで、標準キューからのメッセージのポーリングを継続します。
バッチウィンドウを使用していて、SQS キューのトラフィックがきわめて少ない場合、Lambda は関数を呼び出す前に最大 20 秒間待機することがあります。これは、バッチウィンドウを 20 秒未満に設定した場合であっても同様です。
注記
Java では、JSON を逆シリアル化するときに null ポインタエラーが発生することがあります。これは、「Records」と「eventSourceARN」のケースが JSON オブジェクトマッパーによってどのように変換されるかに起因している可能性があります。
FIFO キューメッセージイベントの例
FIFO キューの場合、レコードには、重複除外と順序付けに関連する追加属性が含まれます。
例 Amazon SQS メッセージイベント (FIFO キュー)
{ "Records": [ { "messageId": "11d6ee51-4cc7-4302-9e22-7cd8afdaadf5", "receiptHandle": "AQEBBX8nesZEXmkhsmZeyIE8iQAMig7qw...", "body": "Test message.", "attributes": { "ApproximateReceiveCount": "1", "SentTimestamp": "1573251510774","SequenceNumber": "18849496460467696128", "MessageGroupId": "1","SenderId": "AIDAIO23YVJENQZJOL4VO","MessageDeduplicationId": "1","ApproximateFirstReceiveTimestamp": "1573251510774" }, "messageAttributes": {}, "md5OfBody": "e4e68fb7bd0e697a0ae8f1bb342846b3", "eventSource": "aws:sqs", "eventSourceARN": "arn:aws:sqs:us-east-2:123456789012:fifo.fifo", "awsRegion": "us-east-2" } ] }