DynamoDB Streams 完全ガイド(例付き)
DynamoDB Streams は変更データキャプチャのログです。テーブルへのすべての挿入、更新、削除が、順序を保って、 あなたが反応できるレコードのストリームとしてキャプチャされます。ポーリングせずにテーブルをイベントソースに 変える方法です。
監査ログのシナリオでは、機密性の高いイベントが到着した瞬間に反応したいものです — 誰かが請求書をエクスポート したり、管理者ロールを付与したりしたときにアラートを発報する — タイマーでテーブルをスキャンすることなく。 Streams はそのプッシュ側です。
DynamoDB Streams はどのように機能するのか?
DynamoDB Streams は、テーブルへのすべての挿入、更新、削除を、時間順で重複排除されたレコードのログとして
キャプチャし、最大24時間保持します。各レコードが何を運ぶかを StreamViewType(キー、新しいイメージ、
古いイメージ、またはその両方)で選び、それから Lambda トリガーでストリームを消費して、ポーリングせずに
アイテムの変更に反応します。
- Streams はアイテムレベルの変更をキャプチャする、時間順で重複排除されたログとして、最大24時間保持します。
- 各レコードが何を運ぶかを選ぶ、
StreamViewTypeで。キーのみ、新しいイメージ、古いイメージ、または 古いものと新しいものの両方。 - レコードはアイテムごとに順序付けられる — 1つのアイテムへの変更は書き込まれた順に到着します — そして ストリームは と同じ方法でシャーディングされます。
- ネイティブなコンシューマーは Lambda — 新しいレコードのバッチごとに実行されるトリガーで、より豊かな ファンアウトのための代替として Kinesis Data Streams があります。
問題: ポーリングせずに反応する
「role.granted イベントが書き込まれたら知らせて」が必要です。素朴なアプローチは、毎分新しいイベントを
スキャンするスケジュールされたジョブです — これは毎回、直近のパーティション全体を読み、キャパシティを消費し、
常に少なくとも1分遅れます。
あなたが本当に欲しいのはプッシュです。アイテムが変わった瞬間に DynamoDB が知らせてくれるのです。 それがまさに Streams が提供するもので、変更レコードは、あなたが探し回るのではなく、あなたのコードに配信されます。
Streams の仕組み
AWS のドキュメントによれば、DynamoDB Streams は変更の重複排除された時間順のログを最大24時間保持し、 ネイティブな Lambda 統合を備えています (DynamoDB の変更データキャプチャ)。 各レコードは1つのアイテムレベルの変更を記述します。
ストリームを有効にするとき、StreamViewType を選びます。これは各レコードが変更されたアイテムをどれだけ
運ぶかを制御します。
| StreamViewType | each record contains |
|---|---|
| KEYS_ONLY | only the key attributes of the changed item |
| NEW_IMAGE | the entire item as it looks after the change |
| OLD_IMAGE | the entire item as it looked before the change |
| NEW_AND_OLD_IMAGES | both the before and after images |
レコードはアイテムごとに順序付けられます — 単一のアイテムへの変更は書き込まれた順に現れます — そして ストリームはテーブルと同じパーティション構造に沿ってシャーディングされます。保持は24時間です — Streams は 反応のためのバッファであって、恒久的な履歴ではありません。恒久的な履歴のためには、イベントそのものを格納します (それはまさに、私たちの監査ログのテーブルがすでにそうであるものです)。
ネイティブなコンシューマーは Lambda トリガーです。DynamoDB は、新しいストリームレコードのバッチが 到着すると、それを引数にあなたの関数を呼び出します。
実例: 機密性の高い監査イベントでアラートを出す
監査ログのテーブルには NEW_IMAGE のストリームを付けるので、各レコードは完全な新しいイベントを運びます。
Lambda がバッチを消費し、重要なレコードだけを転送します。
| stream record (NEW_IMAGE) | consumer action | ||
|---|---|---|---|
| TENANT#acme | EVENT#…#a2 | action=invoice.export | send to SIEM |
| TENANT#globex EVENT#…#b9 action=role.granted | page on-call | ||
| TENANT#acme | EVENT#…#a1 | action=login.success | ignore |
その関数はテーブルには一切触れません — ストリームが渡すものだけに純粋に反応します。ポーリングも、スキャンも なく、アラートは書き込みから数秒以内に発報します。ストリームレコードはアイテムごとに順序付けられるので、 同じイベントアイテムへの連続した変更は、書き込まれた順に到着します。
これは下流のコピーを維持する標準的な方法でもあります。ストリームコンシューマーは、各イベントを 全文の監査検索のために OpenSearch に射影したり、カウントを集計したりできます — すべて同じ変更ログから 導出されます。
DynoTable でやってみる
ストリームコンシューマーを配線する前に、Lambda が受け取るアイテムの正確な形 — どの属性が存在するか、
ネストしたマップやリストがどう見えるか、NEW_IMAGE レコードが実際に何を含むか — を知る必要があります。
サンプルアイテムをプレーンな JSON とストリームレコードが使う属性値の形の間で変換するには、
DynamoDB JSON コンバーター がブラウザ内でそれを行います。そして
DynoTable では、完全なアイテム — DynamoDB-JSON 形式も含む — を検査できるので、フィールドの形を推測する
代わりに、実データに対して NEW_IMAGE レコードをモデリングできます。

コンシューマーをローカルでテストしているなら、テーブルを DynamoDB Local に対して実行し、同じ方法で検査 しましょう — DynamoDB Local に接続するを参照してください。
落とし穴と次のステップ
- 24時間はバックログではない。 コンシューマーが1日ダウンすると、レコードは期限切れになり、消え去ります。 Streams はニアリアルタイムの反応のためのものであって、耐久性のあるリプレイのためではありません — 履歴のためにはイベントそのものを保持しましょう。
- 必要な最小の
StreamViewTypeを選ぶ。NEW_AND_OLD_IMAGESはペイロードを2倍にします。アイテムを 読み直すためにキーだけが必要なら、KEYS_ONLYのほうが安価です。 - 順序付けはアイテムごとであって、パーティションキーごとやグローバルではない。 DynamoDB は同じアイテムへの 連続した変更についてのみ順序を保証します。異なるアイテム間では、たとえ1つのパーティションキー内であっても、 順序の保証はありません。
- TTL の削除はストリームレコードとして現れる、システム属性のマーカー付きで。これが期限切れのアイテムを アーカイブする方法です — DynamoDB TTLを参照してください。
Streams は監査ログをイベントソースに変えます。次の運用上の関心事は、アイテムのライフサイクルの反対の端 — DynamoDB TTL で古いイベントを自動的に期限切れにすること — です。
DynoTable をダウンロード して、Lambda コードを1行書く前に、ストリームコンシューマーが 受け取る正確なアイテムの形を検査しましょう。


