DynamoDB Streams を Lambda のトリガーで使う話

9K Views

March 29, 23

スライド概要

JAWS-UG 名古屋 推しの AWS サービスを語る LT 会 2023/03/29

profile-image

Qiita や Zenn でいろいろ書いてます。 https://qiita.com/hmatsu47 https://zenn.dev/hmatsu47 MySQL 8.0 の薄い本 : https://github.com/hmatsu47/mysql80_no_usui_hon Aurora MySQL v1 → v3 移行計画 : https://zenn.dev/hmatsu47/books/aurora-mysql3-plan-book https://speakerdeck.com/hmatsu47

シェア

またはPlayer版

埋め込む »CMSなどでJSが使えない場合

関連スライド

各ページのテキスト
1.

DynamoDB Streams を Lambda のトリガーで使う話 JAWS-UG 名古屋 推しの AWS サービスを語る LT 会 2023/3/29 まつひさ(hmatsu47)

2.

自己紹介…は時間省略のためスキップ 松久裕保(@hmatsu47) ● https://qiita.com/hmatsu47 2

3.

本日のネタは ● RDS / Aurora 3

4.

本日のネタは ● RDS / Aurora 4

5.

本日のネタは ● RDS / Aurora ではなく DynamoDB + Lambda ● データ登録用の DynamoDB テーブルでストリームを設定 ● それをトリガーに Lambda を実行させる話 ○ 元テーブルのデータを加工して別テーブルにコピーする ○ Lambda で何らかの非同期 API を呼び出す ■ 「中身が見えるキュー」としての使い方 5

6.

どういうときに使う? ● 違う設計の参照用テーブルを(複数)用意したいケース ○ インデックスの数が多すぎる ■ GSI は 20 個まで、LSI は 5 個まで ○ 後から LSI を追加したくなった ○ 参照用テーブルに必要なパーティションキーまたはソートキーが 非正規形で、テーブルごとに値の組み合わせを変えたい ■ 例)テーブル A では登録日+ユーザー ID、テーブル B では ユーザー ID + 商品 ID をパーティションキーにしたい 6

7.

どういうときに使う? ● 「中身が見えるキュー」として使いたいケース ○ アプリケーションの実装者がキューの扱いに慣れていない ■ キューの中身が見えないと不安 ○ 中身を確認後「キューの一部だけ選んで Lambda 再発火」したい ■ レコードを変更して保存すれば再びストリームに流れる ○ ベストプラクティスは別にあるとしても、使う人に合わせた技術 (処理方法)選定があっても良いのでは? 7

8.

使用例(1/2) ● blastengine API でメール送信 ○ 送信用テーブルに挿入・変更すると、 ↑ ここ (ストリーム) ○ Streams をトリガーに Lambda を起動 ■ blastengine API にリクエストし、 ■ 成功したら送信履歴テーブルに記録 ● ■ 送信用テーブルのレコードは削除 失敗したら時間をあけてリトライ ● レートリミット対策 ○ バウンス処理部分の図示・説明は省略 8

9.

使用例(2/2) ● Qiita 記事はこちら ○ https://qiita.com/hmatsu47/items/e6e8fc9290eede7c8a55 ○ API コールを失敗したレコードだけが送信用テーブルに残る ■ 必要があれば対象レコードの変更で Lambda 再発火 ○ 送信履歴テーブルはバウンス(Webhook で取得)と突合する ■ ここでは説明を省略 9

10.

実行例(送信用テーブルに挿入) 10

11.

実行例(送信用テーブル : API コール失敗レコードが残る) 11

12.

実行例(送信履歴テーブル : API コール成功レコードのみ) 12

13.

実行例(実際に届いたメール) 13

14.

トリガーの設定例(1/3) 挿入・更新・削除レコードを 最大 100 件ずつまとめて Lambda に渡す 挿入・更新・削除レコードを まとめるために待機する秒数 14

15.

トリガーの設定例(2/3) Lambda 関数の実行がエラー になったときの再試行回数 (デフォルトは -1: 無制限) チェックするとエラー再試行時 にレコード行数を半分に分割 15

16.

トリガーの設定例(3/3) 同一シャードから 同時に呼び出される Lambda は 1 つ 挿入・更新時のみ Lambdaを呼び出す 16

17.

注意点(1/2) ● 1 テーブルで複数ストリームが流れる ○ シャード単位でストリームが分かれるので、挿入・更新・削除の 順序が完全に保証されるわけではない ■ 1 シャード 複数パーティション・1 パーティション複数シャードの両方あり ○ 一方で、ストリームごとの Lambda の処理時間が長すぎると処理 が詰まってしまう ■ Step Functions を呼び出す形を検討 17

18.

注意点(2/2) ● デフォルトでは Lambda のトリガー再試行は無制限 ○ 処理途中に捕捉し損ねたエラー・例外があると課金死の危険が ■ エラー・例外の捕捉漏れが無いようにする ■ 再試行の回数を限定しておいたほうが良い 18

19.

まとめ ● DynamoDB の制約に引っ掛かる場合に使える ○ インデックスが多すぎる or LSI を追加したいけどできない ● 「中身が見えるキュー」として使える ○ 中身を見た上で選択的に Lambda を再発火させることも ● ストリームの順序と無限再試行に注意 ○ 順序の保証が必要な場合は使わない ○ 再試行の回数を限定して課金死を防ぐ 19