Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

本日のネタは ● RDS / Aurora 3

Slide 4

Slide 4 text

本日のネタは 4 ● RDS / Aurora

Slide 5

Slide 5 text

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

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

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

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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