![]() |
| Amazon SQS |
はじめに
前回まで、DynamoDB Streams x Lambda のイベント駆動がどこまでスケールするかを確かめてきました。結論は「後続処理の同時実行は S × P(オープンシャード数 × ParallelizationFactor)で律速され、シャードを増やせる限界まで増やしてもLambdaの同時実行数は最大 640 止まり。同時実行枠 1,000 には届かなかった」というものでした。
限界を超える次の一手が「SQS を挟む」ことです。SQS をソースにした Lambda は、Streams のシャード数と無関係にスケールします。
今回は実測の前段として、DynamoDB Streams から SQS につなぐまでの構成を整理してみます。
まずは結論から
- Streams から SQS への入口は EventBridge Pipes と 中継 Lambda の 2 方式
- 下流(SQS と worker Lambda)は共通なので、構成の違いは入口だけ
- worker の到達多重には入口の供給レートが重要
前提となる構成
Lambda直接続の壁(S×Pの上限)
前回では「DynamoDB Streams を後続処理用の Lambda が直接読む」構成でした。後続処理の同時実行の上限は次の式で決まります。
後続処理の同時実行 ≒ S × P ÷ D × 0.84
S = オープンシャード数(テーブルのパーティション数)
P = ParallelizationFactor(シャードあたりの並列読み出し数)
D = 1 件あたりの処理時間
S × P は、前回シャードを増やせるだけ増やして S=64(P=10)の 640 が上限でした。ただし 640 は目一杯増やした場合の天井です。軽い利用ではシャードは 1 つ程度にとどまるので、Lambda の多重度は P の最大値の 10 前後になります。構成にすると次のとおりです。
SQSを挟む狙い
Streams と後続処理(worker Lambda)の間に SQS(標準キュー) を挟みます。
- 入口は、Streams の変更を SQS に詰め替えるだけの軽い中継です。
- worker の同時実行は SQS イベントソースマッピングが決めます。シャード数とは無関係です。
S × P が握るのは「入口の供給レート」だけになり、worker 側の多重起動とは切り離されるはずです。SQS がバッファとして供給と消費をデカップリングする、という構図です。
方式ごとの構成
SQS 投入の入口として利用できる方式を整理します。
EventBridge Pipes(方式A)
Streams をソース、SQS をターゲットに指定するだけの、マネージドな構成です。
| 項目 | 内容 |
|---|---|
| 活用リソース | EventBridge Pipes |
| つなぎ方 | Pipes のソースに Streams、ターゲットに SQS を指定 |
| 自前コード | 不要(設定のみ) |
| Lambda 同時実行枠 | 入口では使わない |
| 入口の可観測性 | 入口の詳細なメトリクスは見づらい想定 |
ターゲットが SQS の場合、ソース側の batchSize は 10 以下にする必要があります(SQS の SendMessageBatch が 1 回 10 件までのため)。超えるとデプロイが失敗します。
中継Lambda(方式B)
自前の Lambda(以降 relay)が中継役となり Streams をイベントソースマッピングで読み、SendMessageBatch で SQS に送る構成です。
| 項目 | 内容 |
|---|---|
| 活用リソース | Lambda |
| つなぎ方 | relay Lambda が Streams を読み、SQS へ SendMessageBatch
|
| 自前コード | 必要(詰め替えロジック) |
| Lambda 同時実行枠 | relay が枠を使う(worker の取り分が目減りし得る) |
| 入口の可観測性 | IteratorAge や同時実行をメトリクスで見られる |
IteratorAge は、relay が Streams から読み出している位置が「今」からどれだけ遅れているかを表すメトリクスです。値が大きいほど、読み出しが流入に追いついていません。
2方式の違い
下流(SQS と worker)は共通なので、構成上の違いは入口だけです。前回の Streams 直結と並べると、次のようになります。
| 観点 | 方式A Pipes | 方式B 中継 Lambda |
|---|---|---|
| 構成要素 | Pipes | Lambda(ESM付き) |
| 自前コード | なし | あり |
| Lambda 枠の消費 | なし | あり |
| 入口の観測 | 難しい | しやすい |
2方式の違いは、SQS への供給をどうやるかです。Pipes はコードも同時実行枠も要らない代わりに、入口の様子は見づらくなります。中継 Lambda はコードと同時実行枠を使う代わりに、IteratorAge などで入口の状態を見られます。
実験前の条件整理
到達多重の目安
worker の同時実行は、おおまかに「SQS への到着レート × 1 件あたりの処理時間」で決まります(リトルの法則)。検証では 1 件あたり約 3 秒の擬似処理を入れる予定なので、worker を MaximumConcurrency=1000 に張り付かせるには、およそ毎秒 330 件前後を SQS に供給し続ける必要がある計算です。
到達多重 ≒ 到着レート(件/秒) × 処理時間(秒)
1000 ≒ 約 330 件/秒 × 3 秒
つまり worker 側の設定が 1,000 でも、入口がこのレートで供給できなければ、worker は途中までしか伸びません。重要なのは、入口がこのレートで供給できるかどうかです。
入口の供給レートを決める設定
入口の供給レートは、1 回に運ぶ件数と、それを同時にいくつ処理するか(並列度)で変わってきます。供給レートを決める設定は、方式ごとに次のとおりです。
| 方式 | 1 回に運ぶ件数 | 並列度 |
|---|---|---|
| 方式A Pipes | ソース設定の batchSize(SQS がターゲットの場合は 10 以下) |
ソース設定の ParallelizationFactor
|
| 方式B 中継 Lambda | イベントソースマッピングの batchSize(既定 100) |
イベントソースマッピングの ParallelizationFactor(P)。前回と同じく S × P で決まる |
方式Aの Pipes は DynamoDB Streams をソースにする場合の設定に ParallelizationFactor があります。シャードあたり同時に処理するバッチ数を指定するもので、設定値は1〜10、既定は 1 です。Lambda のイベントソースマッピングと同じ名前の設定です。
方式Bの中継 Lambda は、確認済みの S × P の仕組みがそのまま当てはまります。SQS への送信は 1 回 10 件までですが、relay が受け取ったバッチを 10 件ずつに分けて送るので、batchSize は 10 に縛られません。
まとめ
DynamoDB Streams から SQS への入口は、EventBridge Pipes と中継 Lambda の 2 方式があります。
- 構成: Pipes は設定のみで Lambda 枠を使わず、中継 Lambda は自前コードで構築
- 共通部分: SQS と worker Lambda は同じ。違いは入口だけ
- 目安: 擬似処理 3 秒で 1,000 多重に張り付かせるには、毎秒 330 件前後の供給が要る
次回は、この 2 方式を実際に流し、worker Lambda が 1,000 多重に届くかを確かめてみます。





