1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【DynamoDB Streams x SQS】ストリームの接続方式を整理する

1
Posted at
                                            
Amazon SQS.png
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 前後になります。構成にすると次のとおりです。

aws-dynamodb-streams-sqs-prev-direct.png

SQSを挟む狙い

Streams と後続処理(worker Lambda)の間に SQS(標準キュー) を挟みます。

aws-dynamodb-streams-sqs-why-sqs.png

  • 入口は、Streams の変更を SQS に詰め替えるだけの軽い中継です。
  • worker の同時実行は SQS イベントソースマッピングが決めます。シャード数とは無関係です。

S × P が握るのは「入口の供給レート」だけになり、worker 側の多重起動とは切り離されるはずです。SQS がバッファとして供給と消費をデカップリングする、という構図です。

方式ごとの構成

SQS 投入の入口として利用できる方式を整理します。

EventBridge Pipes(方式A)

Streams をソース、SQS をターゲットに指定するだけの、マネージドな構成です。

aws-dynamodb-streams-sqs-method-a-pipes.png

項目 内容
活用リソース EventBridge Pipes
つなぎ方 Pipes のソースに Streams、ターゲットに SQS を指定
自前コード 不要(設定のみ)
Lambda 同時実行枠 入口では使わない
入口の可観測性 入口の詳細なメトリクスは見づらい想定

ターゲットが SQS の場合、ソース側の batchSize は 10 以下にする必要があります(SQS の SendMessageBatch が 1 回 10 件までのため)。超えるとデプロイが失敗します。

中継Lambda(方式B)

自前の Lambda(以降 relay)が中継役となり Streams をイベントソースマッピングで読み、SendMessageBatch で SQS に送る構成です。

aws-dynamodb-streams-sqs-method-b-relay.png

項目 内容
活用リソース Lambda
つなぎ方 relay Lambda が Streams を読み、SQS へ SendMessageBatch
自前コード 必要(詰め替えロジック)
Lambda 同時実行枠 relay が枠を使う(worker の取り分が目減りし得る)
入口の可観測性 IteratorAge や同時実行をメトリクスで見られる

IteratorAge は、relay が Streams から読み出している位置が「今」からどれだけ遅れているかを表すメトリクスです。値が大きいほど、読み出しが流入に追いついていません。

2方式の違い

下流(SQS と worker)は共通なので、構成上の違いは入口だけです。前回の Streams 直結と並べると、次のようになります。

aws-dynamodb-streams-sqs-compare.png

観点 方式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 多重に届くかを確かめてみます。

参考リンク

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?