JAWS-UG 名古屋 推しの AWS サービスを語る LT 会 2023/03/29
DynamoDB Streams をLambda のトリガーで使う話JAWS-UG 名古屋 推しの AWS サービスを語る LT 会2023/3/29まつひさ(hmatsu47)
View Slide
自己紹介…は時間省略のためスキップ松久裕保(@hmatsu47)● https://qiita.com/hmatsu472
本日のネタは● RDS / Aurora3
本日のネタは4● RDS / Aurora
本日のネタは● RDS / Aurora ではなく DynamoDB + Lambda● データ登録用の DynamoDB テーブルでストリームを設定● それをトリガーに Lambda を実行させる話○ 元テーブルのデータを加工して別テーブルにコピーする○ Lambda で何らかの非同期 API を呼び出す■ 「中身が見えるキュー」としての使い方5
どういうときに使う?● 違う設計の参照用テーブルを(複数)用意したいケース○ インデックスの数が多すぎる■ GSI は 20 個まで、LSI は 5 個まで○ 後から LSI を追加したくなった○ 参照用テーブルに必要なパーティションキーまたはソートキーが非正規形で、テーブルごとに値の組み合わせを変えたい■ 例)テーブル A では登録日+ユーザー ID、テーブル B では ユーザー ID +商品 ID をパーティションキーにしたい6
どういうときに使う?● 「中身が見えるキュー」として使いたいケース○ アプリケーションの実装者がキューの扱いに慣れていない■ キューの中身が見えないと不安○ 中身を確認後「キューの一部だけ選んで Lambda 再発火」したい■ レコードを変更して保存すれば再びストリームに流れる○ ベストプラクティスは別にあるとしても、使う人に合わせた技術(処理方法)選定があっても良いのでは?7
使用例(1/2)● blastengine API でメール送信○ 送信用テーブルに挿入・変更すると、○ Streams をトリガーに Lambda を起動■ blastengine API にリクエストし、■ 成功したら送信履歴テーブルに記録● 送信用テーブルのレコードは削除■ 失敗したら時間をあけてリトライ● レートリミット対策○ バウンス処理部分の図示・説明は省略8↑ここ(ストリーム)
使用例(2/2)● Qiita 記事はこちら○ https://qiita.com/hmatsu47/items/e6e8fc9290eede7c8a55○ API コールを失敗したレコードだけが送信用テーブルに残る■ 必要があれば対象レコードの変更で Lambda 再発火○ 送信履歴テーブルはバウンス(Webhook で取得)と突合する■ ここでは説明を省略9
実行例(送信用テーブルに挿入)10
実行例(送信用テーブル : API コール失敗レコードが残る)11
実行例(送信履歴テーブル : API コール成功レコードのみ)12
実行例(実際に届いたメール)13
トリガーの設定例(1/3)14挿入・更新・削除レコードを最大 100 件ずつまとめてLambda に渡す挿入・更新・削除レコードをまとめるために待機する秒数
トリガーの設定例(2/3)15Lambda 関数の実行がエラーになったときの再試行回数(デフォルトは -1: 無制限)チェックするとエラー再試行時にレコード行数を半分に分割
トリガーの設定例(3/3)16同一シャードから同時に呼び出されるLambda は 1 つ挿入・更新時のみLambdaを呼び出す
注意点(1/2)● 1 テーブルで複数ストリームが流れる○ シャード単位でストリームが分かれるので、挿入・更新・削除の順序が完全に保証されるわけではない■ 1 シャード 複数パーティション・1 パーティション複数シャードの両方あり○ 一方で、ストリームごとの Lambda の処理時間が長すぎると処理が詰まってしまう■ Step Functions を呼び出す形を検討17
注意点(2/2)● デフォルトでは Lambda のトリガー再試行は無制限○ 処理途中に捕捉し損ねたエラー・例外があると課金死の危険が■ エラー・例外の捕捉漏れが無いようにする■ 再試行の回数を限定しておいたほうが良い18
まとめ● DynamoDB の制約に引っ掛かる場合に使える○ インデックスが多すぎる or LSI を追加したいけどできない● 「中身が見えるキュー」として使える○ 中身を見た上で選択的に Lambda を再発火させることも● ストリームの順序と無限再試行に注意○ 順序の保証が必要な場合は使わない○ 再試行の回数を限定して課金死を防ぐ19