ストリーム処理
データを受信しながらリアルタイムで処理する手法で、バッチ処理と対比される
ストリーム処理とは
ストリーム処理 (Stream Processing) は、到着し続けるデータをためずに、届いたその場で処理していく方式である。バッチ処理が「一定量ためてから一括で処理」するのに対し、ストリーム処理は入力に終わりがないものとして扱う。この「終わりがない」という前提が設計上の分かれ目になる。バッチ処理なら集計対象は「ファイルの最後まで」で確定するが、ストリーム処理では「いつ集計を確定させるか」を自分で決めなければならない。後述するウィンドウとウォーターマークは、この確定タイミングを決めるための仕組みである。
バッチ処理との比較
同じ集計処理でも、レイテンシと確定のしかたが変わる。
| 観点 | バッチ処理 | ストリーム処理 |
|---|---|---|
| レイテンシ | 高い (分〜時間) | 低い (ミリ秒〜秒) |
| データ量 | 大量を一括処理 | 1 件ずつ or 小バッチ |
| 処理タイミング | スケジュール実行 | イベント駆動 |
| 集計の確定 | 入力の終端で確定 | ウィンドウの締めで確定 |
| 用途 | 日次集計、ETL | リアルタイム分析、アラート |
両者は排他ではない。ストリームで即時のアラートを出しつつ、同じデータを保存してバッチで日次の確定値を作り直す構成が実務では多い。ストリーム側は遅延データを取りこぼす可能性があるため、正確さが要る帳票はバッチ側の再計算を正とする。
イベント時刻と処理時刻
ストリーム処理でつまずきやすいのは、「時刻」が 2 種類あることである。
- イベント時刻 (event time): そのイベントが発生元の端末で起きた時刻。通常はレコードの中に埋め込まれて運ばれる。イベント時刻で処理する場合、時間の進みはデータに依存し、処理機の壁時計には依存しない。
- 処理時刻 (processing time): その処理を実行しているマシンのシステム時刻。時間ベースの操作はすべてこの時計で動く。
処理時刻は実装が最も単純で、遅延も最小になる。ただし結果が実行タイミングに左右される。同じ入力を再実行しても、到着の順やタイミングが変われば集計結果が変わるため、再現性がない。イベント時刻なら、到着が乱れても「いつ起きたか」で振り分けるので、再実行しても同じ結果になる。
モバイル端末やオフライン対応アプリのログのように、発生から到着までが数分〜数時間ずれ得る入力では、処理時刻で集計すると「19 時台の売上」に 20 時到着分が混ざる。障害の指標や課金の集計をイベント時刻で組むべきなのはこのためである。
ウィンドウ処理
終わりのないストリームを集計するために、時間やカウントで区切る。この区切りがウィンドウである。
| ウィンドウ | 説明 | 例 |
|---|---|---|
| タンブリング | 固定長、重複なし | 5 分ごとの売上集計 |
| スライディング | 固定長、重複あり | 直近 5 分の移動平均 |
| セッション | 無活動の間隔で区切る | ユーザーセッションの分析 |
スライディングウィンドウは 1 件のイベントが複数のウィンドウに属するため、状態量とスライド幅が反比例する。ウィンドウ長 5 分・スライド 10 秒なら 1 件が 30 個のウィンドウに入り、保持する状態も出力量も 30 倍になる。滑らかなグラフが欲しいという理由だけでスライド幅を詰めると、メモリと出力先の負荷でここが先に壊れる。
セッションウィンドウは長さが固定されず、無活動の間隔 (ギャップ) で切れる。ギャップを長く取ると、活動が続くユーザーのウィンドウがいつまでも閉じず、状態が膨らみ続ける。
ウォーターマークと遅延データ
イベント時刻でウィンドウを締めるには、「イベント時刻がどこまで進んだか」を知る必要がある。それを担うのがウォーターマークで、データストリームの中をタイムスタンプ付きのマーカーとして流れる。ウォーターマーク (t) は「このストリームのイベント時刻は t まで到達した、つまり t 以前のタイムスタンプを持つ要素はもう来ないはずだ」という宣言である。ウィンドウはこの宣言を受けて締められる。
ここに設計上のトレードオフがある。ウォーターマークを最新のイベント時刻ぎりぎりに進めれば結果は早く出るが、遅れて届いたイベントは締め切り後に来る。逆に余裕 (許容する遅れ) を大きく取れば取りこぼしは減るが、その分だけ結果が遅くなる。「リアルタイム」と「完全性」はこの一点で交換関係にある。
ウォーターマークより後に届いたイベントの扱いは、あらかじめ決めておく。捨てる、別の出力へ振り分けて後で突き合わせる、確定済みの結果を更新する、のいずれかである。何も決めないと、静かに捨てられて数字が合わない障害になる。
なお、パーティションが並列に流れている場合、下流のウォーターマークは各入力の最小値で決まる。したがって 1 つのパーティションだけデータが来ないと、そこで全体のイベント時刻が止まり、他のパーティションのウィンドウも締まらない。「一部のシャードだけ流量ゼロ」でウィンドウ出力が止まる詰まりは、この性質から来る。
ストリーム処理の課題
- 順序保証: パーティション (シャード) の内部では順序が保たれるが、パーティション間では保証されない。同じ順序で処理したいレコードは同じパーティションキーに寄せる。ただしキーを寄せすぎると、そのパーティションだけが上限に当たる。
- 重複処理: 障害復旧時の再送で同じレコードが 2 回来る前提で組む。冪等な書き込み (条件付き書き込みや一意キーの upsert) にしておけば、再送されても結果が変わらない。
- バックプレッシャー: 下流が遅いと処理待ちが積み上がる。コンシューマー側の並列度と 1 回に取る件数を調整し、遅れの指標 (未処理レコードの滞留時間) を監視対象にする。
- 状態の巨大化: ウィンドウや重複排除のための状態は、キー数とウィンドウ長の積で増える。保持期限を切らない状態は必ず溢れる。
AWS でのストリーム処理
主要な構成要素は次のとおり (サービス名は 2026 年 8 月時点)。
[データソース] → [Kinesis Data Streams] → [Lambda] → [DynamoDB / S3]
→ [Amazon Data Firehose] → [S3 / Redshift]
- Amazon Kinesis Data Streams: リアルタイムのデータストリーム本体。詳細は Kinesis を参照。
- Amazon Data Firehose: 保存先への配信。旧称は Kinesis Data Firehose で、Kinesis ブランドから独立した名前に変わっている。
- Amazon Managed Service for Apache Flink: ウィンドウやウォーターマークを含む本格的なストリーム処理。旧称は Kinesis Data Analytics for Apache Flink。
- Amazon MSK: Kafka のマネージドサービス。
- AWS Lambda: ストリームのコンシューマー。
- DynamoDB Streams: テーブル変更のキャプチャ。詳細は 変更データキャプチャ を参照。
Lambda をコンシューマーにする構成では、ウィンドウやウォーターマークの管理を自分で書くことになる。イベント時刻でのウィンドウ集計が必要な段階に来たら、Flink のようなストリーム処理エンジンへ移すほうが早い。改称された 2 つは、古い名前でコンソールや資料を探すと見つからない点に注意する。
この記事は役に立ちましたか?
関連用語
Kinesis
AWS のリアルタイムデータストリーミングサービスで、大量のデータを収集 / 処理 / 分析する
変更データキャプチャ (CDC) とは - DB の変更をリアルタイム連携するパターン
変更データキャプチャ (CDC、Change Data Capture) はデータベースの INSERT/UPDATE/DELETE を検出して検索エンジンや分析基盤へリアルタイムに伝播させるデータ統合パターン。実装 4 方式と AWS での構成を解説
イベント駆動アーキテクチャ
イベントの発行と購読を中心にシステムを構成し、サービス間の疎結合と非同期処理を実現するアーキテクチャスタイル
EventBridge
AWS のサーバーレスイベントバスで、イベント駆動アーキテクチャの中核を担う
Apache Kafka
大規模なリアルタイムデータストリーミングのための分散メッセージングプラットフォーム
イベントソーシング
状態の変更をイベントとして記録し、イベントの再生で現在の状態を復元する設計パターン