LoginSignup
10
6

More than 5 years have passed since last update.

DynamoDB StreamをトリガーにしてLambdaを実行する際にストリーム開始位置「水平トリム」を使うと書き込みキャパシティが大変なことになる件

Last updated at Posted at 2018-05-05

DynamoDB Streamとは

DynamoDB Streamは、DynamoDBに対する書込みをイベントトリガーとして利用できる機能です。つまりは特定のDynamoDBテーブルに書き込み(追加、変更、削除)があった場合にイベントが飛んでくるので、それをトリガーとしてLambdaを起動したりできます。使い方の概要このあたりが参考になると思います。

DynamoDB StreamをトリガーにしてLambdaを実行する

やりたかったこと

AWS IoT Core経由でRaspberry Piから飛んでくるセンサーデータを、DynamoDBテーブル(A)に格納しているのですが、このままでは比較的粒度が大きいので、Kibanaとかで可視化しやすいように、Lambdaで細かくバラして別テーブル(B)に格納したかったのです。

Untitled (2).png

定期バッチ処理なども検討しましたが、取りこぼしなく処理することを考えるのが面倒なので、DynamoDB Streamがうってつけでした。

とんでもないキャパシティが要求された

テーブル(A)のストリームイベントをトリガーにLambdaを起動し、加工したデータをテーブル(B)に投入したところ、事件が起こりました。Auto Scalingを利用していたのですが、みるみるうちに容量がうなぎ登りとなり、**キャパシティが5,000を超えてしまいました!**見積額が月額$2,000越え!(涙)

原因は「水平トリム」の利用だった

どう考えても机上の計算をかるく5倍は上回りそうなので悩みましたが、原因はこれでした。

LambdaのトリガーにDynamoDB Streamを設定する際に「開始位置」というのを指定しますが、「水平トリム」と「最新」が選択できて、デフォルトは「最新」です。

Lambda Management Console.png

本家のドキュメントが非常に分かりにくいのですが、「最新」はストリームの新しい方を優先して処理、「水平トリム」は古い方から時系列順に処理するということのようです(この辺はもっと詳しい方がいたら教えてください)。

センサーデータは24時間常時飛んでくるので、時系列順に処理した方が良いだろうと「何となく」思ってしまった自分は「水平トリム」を選択しました。

問題の原因を探るべく、書き込み側のテーブルBを確認したところ、なんと1日前のデータが投入されているではないですか!

自分はてっきりトリガーを購読した時点からのデータがストリームで飛んでくるのかと思ったら、なんと24時間も前のデータから飛んできているようでした。そこから最新のデータに追いつくべく、超高速でストリームイベントが飛んでくるので、それを書き込む側のテーブルのキャパシティがすごいことになってしまったと言うことでしょうか。

その後、開始位置を「最新」にしたトリガーを作り直して設定したところ、キャパシティは一気に400程度まで落ちてくれました。(途中ゼロになったりしたところは、トリガーを一時的に無効にしたり試行錯誤をした形跡)

DynamoDB · AWS Console.png

まぁ、「水平トリム」のままでも、そのまましばらく放置すれば、いずれは最新データに追いついて、その時にはキャパシティは落ち着くとは思うのですが、こういう問題もあるみたいなので、一時的にでも不必要にキャパシティを上げるのは望ましくはないとは思います。

DynamoDBのパーティション分割問題について

いろいろ調べると、DynamoDB Streamは内部的に24時間分のデータを保持しているようなのですね。開始位置を「最新」のままで使った場合には、恐らく過去のデータは捨てられると思いますが、今回は今現在から以降のデータが取れれば良かったので、めでたく解決です。いや、焦りました!

よほど過去の更新データ(といっても最大24時間ですが)が重要な場合以外は「水平トリム」は使わないのが無難かもしれませんね。

10
6
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
10
6