はじめに
リアルタイムデータ処理の世界には 「Watermark(ウォーターマーク)」 という重要な概念があります。
画像の透かし(digital watermark)とは全く別のもので、ストリーム処理における Watermark は 「どこまでデータが届いたかを示す水位線」 のことです。Apache Flink、Apache Kafka、Google Cloud Dataflow など主要なフレームワークすべてで使われる、データエンジニアリングの基礎概念です。
この記事では「ストリーム処理って何?」というところから、Watermark がなぜ必要なのかをやさしく解説します。
まず知っておきたい:2つの「時刻」
Watermark を理解するには、まず 2種類の時刻 の違いを押さえる必要があります。
イベント時刻(Event Time)
データが 実際に発生した時刻 です。たとえば「センサーが温度を測定した時刻」「ユーザーがボタンをクリックした時刻」など、データそのものに埋め込まれたタイムスタンプです。
処理時刻(Processing Time)
データが サーバーに届いて処理された時刻 です。壁掛け時計の時刻とも言えます。
この2つが常に一致するなら話は簡単ですが、現実にはそうはいきません。
【理想】
イベント発生 10:00:00 → サーバー到着 10:00:01 (ほぼ同時)
【現実】
イベント発生 10:00:00 → ネットワーク遅延 → サーバー到着 10:00:30 (30秒遅れ)
イベント発生 10:00:05 → サーバー到着 10:00:06 (ほぼ同時)
イベント発生 10:00:02 → 通信障害 → 再送 → サーバー到着 10:05:00 (5分遅れ!)
データは 必ずしも発生した順番通りに届くわけではない のです。このズレこそが、ストリーム処理の難しさの核心です。
ストリーム処理の「困りごと」
たとえば、IoTセンサーの温度データを 1分ごとの平均 で集計するシステムを考えてみましょう。
「10:00〜10:01の平均温度」を計算したい場合、いつ計算を確定すればいいでしょうか?
10:00:03のデータが届いた ✅
10:00:15のデータが届いた ✅
10:00:45のデータが届いた ✅
10:01:02のデータが届いた → もう次の1分に入った。10:00台は確定?
ここで 10:00:30のデータが通信障害で遅れている としたら、確定してしまうとそのデータは集計に含まれません。
かといって、「いつまでも待ち続ける」のではリアルタイム処理の意味がなくなります。
「いつ、集計を確定していいのか」 ── この判断を助けてくれるのが Watermark です。
Watermarkとは?
Watermark は、「もうこの時刻以前のデータは(おそらく)全部届いた」という宣言です。
由来は水位計(水の高さを示す目盛り)で、「データの到着がどこまで進んだかの水位線」という比喩から来ています。
時間の流れ →
┌────────────────────────────────────────┐
│ データ: ● ● ● ● ● ● ● │
│ │
│ ▼ Watermark = 10:00:50 │
│ ─ ─ ─ ─ ─ ┼ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ │
│ "ここまでは │ "ここから先は │
│ 到着済み" │ まだ届くかも" │
└────────────────────────────────────────┘
もう少し正確に言うと、Watermark はイベント時刻に対する 下限値(lower bound) です。「Watermark が 10:00:50 に達した」とは、「イベント時刻が 10:00:50 以前のデータはもう届かない(はず)」という意味です。
Watermarkの3つの役割
① ウィンドウ(集計区間)の確定タイミングを決める
「10:00〜10:01」のウィンドウ(集計区間)の集計結果を出力するのは、Watermark が 10:01 を超えたときです。Watermark のおかげで、「まだ待つべきか、もう確定していいか」の判断が可能になります。
② 遅延データ(Late Data)を検出する
Watermark が 10:01 を超えた後に 10:00:30 のデータが届いた場合、それは 遅延データ(Late Data) と判定されます。遅延データに対しては、破棄する、別途集計する、結果を修正するなどのポリシーを設定できます。
③ 処理の進捗を測定する
Watermark はストリーム処理パイプライン(データが流れる処理経路全体)の進捗を示す指標としても機能します。Watermark が遅れているなら、何らかのボトルネック(処理の詰まり)やデータの遅延が発生していると分かります。
具体例で理解する
IoTセンサーが5台あり、1分ウィンドウ(1分間の集計区間)で平均温度を集計するケースを追いかけましょう。
=== サーバーの壁時計: 10:01:10 ===
届いたデータ:
センサーA: 10:00:03 → 25.1°C ✅
センサーB: 10:00:15 → 24.8°C ✅
センサーC: 10:00:30 → 25.5°C ✅
センサーD: 10:00:45 → 24.9°C ✅
センサーE: 10:01:02 → 25.3°C ✅ (次のウィンドウ)
現在のWatermark: 10:01:02
→ 10:00台のデータはもう来ないと判断
→ 10:00〜10:01 のウィンドウを確定!
→ 平均温度 = (25.1 + 24.8 + 25.5 + 24.9) / 4 = 25.075°C を出力
=== サーバーの壁時計: 10:03:00 ===
遅延データ到着:
センサーC (再送): 10:00:32 → 25.6°C ⚠️ Late Data!
→ Watermark はすでに 10:01 を超えているため「遅延データ」と判定
→ ポリシーに基づいて処理(破棄 or 結果更新 or サイドアウトプット(別経路への出力))
Watermarkの生成方法
Watermark はシステムが自動で完璧に設定できるものではなく、ヒューリスティック(経験則による推定) に基づいて生成されます。
方法①:固定遅延(最も一般的)
「データは最大でN秒遅れて届く」という仮定のもと、現在届いた最大のイベント時刻からN秒引いた値を Watermark とする方法です。
Watermark = 届いた最大のイベント時刻 − 許容遅延(例: 5秒)
Apache Flink では BoundedOutOfOrdernessWatermarks としてこの方式が標準で提供されています。
// Apache Flink での Watermark 設定例
WatermarkStrategy
.<SensorReading>forBoundedOutOfOrderness(Duration.ofSeconds(5))
.withTimestampAssigner((event, timestamp) -> event.getTimestamp());
方法②:ソースベース
データソース自体が Watermark 情報を持っている場合(例: Apache Kafka のパーティションごとのオフセット情報など)、それを元に生成する方法です。
トレードオフ
Watermark の許容遅延を 長く設定する と遅延データの取りこぼしは減りますが、ウィンドウ(集計区間)の確定が遅くなり レイテンシ(応答遅延)が増加 します。短く設定する とレイテンシは低いですが、遅延データが多く発生します。このバランスは、ビジネス要件に応じて調整が必要です。
主要フレームワークでの扱い
| フレームワーク | Watermark の扱い |
|---|---|
| Apache Flink | 最もネイティブにサポート。WatermarkStrategy APIで宣言的に設定 |
| Apache Kafka Streams |
TimestampExtractor でイベント時刻を抽出し、ストリーム時刻として管理。ウィンドウの grace() で遅延を許容 |
| Google Cloud Dataflow | Watermark の概念を最初に体系化。自動追跡とトリガー(出力タイミングの制御)の組み合わせで制御 |
| Apache Spark Structured Streaming |
withWatermark() メソッドで遅延閾値を指定 |
概念としてはどのフレームワークも共通ですが、APIの設計や挙動の細部は異なります。
歴史的背景
Watermark の概念が広く知られるようになったのは、2015年にGoogleが発表した論文 「The Dataflow Model」 がきっかけです。主著者は Tyler Akidau 氏で、この論文は VLDB(国際データベース学会)で発表されました。
この論文はのちにApache Beam / Google Cloud Dataflow の設計基盤となり、Apache Flink をはじめとする他のフレームワークにも大きな影響を与えました。Tyler Akidau 氏はその後「Streaming 101」「Streaming 102」という解説記事を O'Reilly に寄稿し、ストリーム処理の入門教材として広く読まれています。
まとめ
| キーワード | 一言で言うと |
|---|---|
| Watermark | 「ここまでのデータはもう届いた」という水位線 |
| イベント時刻 | データが実際に発生した時刻 |
| 処理時刻 | データがサーバーで処理された時刻 |
| 遅延データ | Watermark を超えた後に届いたデータ |
| トレードオフ | 許容遅延を長くする ↔ レイテンシ(応答遅延)が増加する |
Watermark は「リアルタイム処理の信頼性」を支える縁の下の力持ちです。ストリーム処理を始める方は、まず「イベント時刻と処理時刻の違い」と「Watermark が何を解決しているか」を押さえることで、フレームワーク固有のAPIも格段に理解しやすくなるはずです。
参考: