51. Kinesisは追記ログ — 読んでも消えないから複数の読者が独立に進める
Kinesisが「読んでも消えないログ」であること、そして複数の読者が互いに邪魔せず同じデータを進めるしくみを、上から下へ図で追っていきます。
① ストリーム = シャードの集合、シャード = 追記されるレコードの列
- 「A Kinesis data stream is a set of shards. Each shard has a sequence of data records. Each data record has a sequence number that is assigned by Kinesis Data Streams.」(key-concepts)
- data blobは最大1MB。Kinesisは中身を解釈も変更もしない(immutable sequence of bytes)。
- sequence numberは書き込み(putRecord / putRecords)の後にKinesisが採番し、「同一シャード内でpartition keyごとに一意」。同じpartition keyのsequence numberは概して時間とともに大きくなる。
- partition key(Unicode文字列、最大256文字)はMD5ハッシュで128ビット整数に写像され、各シャードのハッシュキーレンジによってレコードの行き先シャードが決まる。(key-concepts)
ストリームの実体は「末尾にレコードを追記し続ける列(シャード)」の集まり。DynamoDB編のStreams(変更ログ)で見た「追記ログ」構造そのもので、Kinesisはそれを汎用イベントのために提供したもの。書き込みは常に末尾へ、途中の書き換えや削除は起きない。
② 読んでもレコードは消えない — 消えるのは「保持期間の満了」だけ
- 「The retention period is the length of time that data records are accessible after they are added to the stream. A stream's retention period is set to a default of 24 hours after creation.」(key-concepts)— いつまで読めるかを決めるのは「追加からの経過時間」であって、誰かが読んだかどうかではない。
- 保持期間の可変レンジ:最小24時間〜最大8760時間(365日)。IncreaseStreamRetentionPeriodで延長、DecreaseStreamRetentionPeriodで短縮。24時間を超える保持は追加課金。(key-concepts)
- 耐久性の面でも公式は「The elasticity of Kinesis Data Streams enables you to scale the stream up or down, so that you never lose data records before they expire.」と述べる(introduction)— 期限(expire)前にレコードが失われることはない、という保証。
ここがSQSとの本質的な分かれ目。レコードは「消費されたから消える」のではなく「保持期間が来たから消える」。読み取りは非破壊で、同じレコードが期限まで残り続ける。この一点が、次の「複数の読者が独立に進める」を可能にする土台になる。
③ 位置(カーソル)は読者ごと — だから複数アプリが同時・独立に進める
- 「There can be multiple applications for one stream, and each application can consume data from the stream independently and concurrently.」(key-concepts)
- Kinesis Client Library(KCL)は、データ消費に関するメタデータ(どこまで読んだか等)をDynamoDBテーブルに保存する(現行KCLはアプリごとに3テーブルを作成)。アプリ名はAWSアカウント+リージョン内で一意で、DynamoDBの管理テーブル名として使われる。つまり「読み取り位置」はストリーム側ではなくアプリ側に紐づき、読者ごとにカーソルが独立する。(key-concepts / Kinesis Client Library, Application Name)
ログは1本を共有するが、「どこまで読んだか」は読者ごとに別々に持つ。だから集計アプリが先に進んでいても、アーカイブアプリは自分のペースで後ろから読める。Lambda編で見たストリーム系のイベントソースマッピングが「シャードごとにカーソルを進めるpull型」だったのと同じ発想で、カーソルの持ち主が消費側にいるのがポイント。
④ 公式の型:1本のストリームを「集計」と「S3アーカイブ」が同時に読む
- 「two applications can read data from the same stream. The first application calculates running aggregates and updates an Amazon DynamoDB table, and the second application compresses and archives data to a data store like Amazon S3. The DynamoDB table with running aggregates is then read by a dashboard for up-to-the-minute reports.」(introduction)
- 「multiple actions, like archiving and processing, can take place concurrently and independently.」(introduction)
これはこちらの創作ではなく公式ドキュメントが挙げる代表例。1本のログを、性質のまったく違う2つの用途(リアルタイム集計 / 低コストな長期保管)が奪い合わず同時に使える。②の非破壊性と③の読者ごとカーソルが揃ってはじめて成り立つ構図。
⑤ SQSとの本質差 — 「破壊的読み取りのキュー」対「非破壊の共有ログ」
- Kinesis側の根拠:読み取りは非破壊、レコードは保持期間まで残る、位置は読者ごと(前掲key-concepts / introductionの各記述)。
- 対比の軸は「排他して1回だけ処理させる(キュー)」か「同じ事実を全員が独立に読む(ログ)」か。SQSの可視性タイムアウト・at-least-once・冪等性は既習(SQS/Lambda編)。この編ではKinesis側の「ログ」の性質を確定させるのが目的。
選択の判断軸はここに集約される。「1つの仕事を誰か1人にやらせて片付けたい」ならキュー(SQS)、「起きた事実を複数の用途が独立に読みたい/後で読み直したい」ならログ(Kinesis)。同じ「メッセージを運ぶ」でも、消えるか残るかで設計が根本から変わる。
⑥ リプレイはログ構造の当然の帰結 — 過去に戻ってやり直せる
- カーソルは消費側(KCLがDynamoDBに保存する消費メタデータ)が持つ「ただの位置」なので、保持期間内なら過去のsequence numberへ戻して読み直せる。レコードは読んでも消えないため、同じデータを何度でも再処理できる(②③の帰結)。
- 戻れる範囲は保持期間そのもの:デフォルト24時間、延長すれば最大8760時間(365日)ぶん過去まで。(key-concepts)
リプレイはKinesisの「追加機能」ではなく、非破壊ログ+読者ごとカーソルという構造から自動的に出てくる性質。だから「新しい集計を過去データに当てたい」「バグ修正後に取りこぼしを再処理したい」が、保持期間の範囲でそのまま実現できる。キュー(消費=消滅)には原理的に無い芸当。