💬
AWS Lambdaを直列かつBatch処理するのにDynamoDBを使ってみる
この記事は何
- 1回あたりの実行時間がそこそこ長く、さらに処理を直列に実行する必要がある時、Lambdaのタイムアウトにひっかからないように無理やり対処した時の備忘録です。
- 例えばどんなケースかというと、クローリングの実行間隔をrobots.txtで指定されている場合です。クローリング間隔10秒×クローリング対象100ページとかになると、実行時間が1000秒となり、クローラをLambdaで構成した場合、最長実行時間の900秒を超過してしまいます。
- 本当にやりたいことは、実行 → 10秒wait → 実行を、対象がなくなるまで繰り返すStepFunction的な処理です。ただ自分で経験が無い&イレギュラーな対応であったため今回は見送りました。DynamoDBをQueのように使う方法でゴリゴリ進めました。
実装
- DynamoDBのStreamを主軸にシステムを構成しました。(図にするまでも無いですが…)
- 処理内容をDynamoDBに書き込むLambda(お名前:Pub)と、DynamoDBストリームをトリガにスクレイピングを実行するLambda(お名前:Sub)を構築しました。
- 唯一のポイントはDynamoDBストリームのバッチサイズ指定です。1回の処理時間と、LambdaのTimeout時間を加味してバッチサイズを決める必要があります。例えばTimeout=900秒(指定できるMAX)、1回の処理時間が10秒であれば、バッチサイズは90以下(余裕を見てもう少し小さくしたほうが良いですが)でなければなりません。
振り返って
- 本当はSQSのFIFOキューとかを使う方が素直なのかな。。。と思います。使ったことがなかったので手を出しませんでしたが…。
- Lambdaの中で待ち時間を持たせること自体、どうにかして無くせないものかと思案しています。やっぱりStep Functionなのでしょうか?知見をお持ちの方がいれば、ぜひコメントを…!
Discussion