Flink 基礎#
内容参考自:
有状態ストリーム処理#
概念#
従来のバッチ処理:データを継続的に収集し、時間を基準にバッチを分割し、定期的にバッチ計算を実行する。このような場合に考えられるシナリオの問題:
- 1 時間をバッチの基準とした場合、特定のイベントの変換回数を統計する必要がある。変換が 58 分に始まり、次の時間の 7 分に終了する場合、どのようにしてバッチを超えたデータ統計を完了するのか?
- データが生成されてから受信されるまでの時間は一定ではなく、あるイベントが A より早く発生したが、到着時間が A より遅い場合、このような受信した時間の順序が逆転する問題をどのように処理するのか?
理想的な方法は:
状態(State)
メカニズムを導入し、状態を蓄積し維持する。蓄積された状態は過去の歴史の中で受け取ったすべての歴史的イベントを表し、出力結果に影響を与える。Time時間メカニズム
: データの完全性を操作するメカニズムがあり、特定の時間帯のデータがすべて受信された後にのみ、出力結果を計算する。
これがいわゆる有状態ストリーム処理である。
有状態ストリーム処理の課題#
- 状態フォールトトレランス (State Fault Tolerance):
- 状態管理 (State Management):
- イベント時間処理 (Event-time processing):
- 状態保存と移行 (Savepoints and Job Migration):
状態フォールトトレランス#
簡単なシナリオの正確に一度 (Exactly-once) フォールトトレランス保証:
無限ストリームのデータが入るが、後ろは単一のプロセスの計算である。この場合、プロセスが正確に一度の状態フォールトトレランスを確保するためには、各データを処理し、状態を変更した後にスナップショットを行う。スナップショットはキューに含まれ、対応する状態と比較され、一致するスナップショットが完成すれば、正確に一度を確保できる。
分散状態フォールトトレランス#
-
分散シナリオでは、複数のノードがローカル状態の変更を行うが、
Global consistent snapshot
(全域一致性のスナップショット) は 1 つだけ生成される。 -
checkpoint
チェックポイントメカニズムに基づいてフォールトトレランス回復を行う。 -
simple lamport
アルゴリズムメカニズムに基づく拡張実装で分散スナップショット
を実現し、Flink は計算を中断することなくGlobal consistent snapshot
(全域一致性のスナップショット) を継続的に完成させることができる。大まかな方法は、Flink がデータストリームにチェックポイントバリアフラグを挿入し、以降のオペレーターがデータストリームでチェックポイントバリア N を受け取った後に自分の状態を保存する。このようにして、最初のデータソースから計算が完了するまで、このチェックポイント保存状態が確立される。さらに、チェックポイントバリア N+1、N+2 も同時にデータストリームで同期して行われるため、計算を妨げることなく継続的にチェックポイントを生成できる。
状態管理#
Flink が現在サポートしている方法は:
-
JVM Heapストレージ状態
: 状態量が少ない場合に適している。なぜなら、直接 JVM ヒープに保存され、状態を読み取る必要があるときは、直接 Java オブジェクトで読み書きされ、シリアライズは必要ない。しかし、チェックポイントが各計算値のローカル状態を分散スナップショットに入れる必要がある場合は、シリアライズが必要になる。 -
RocksDBストレージ状態
: コア外の状態バックエンドの一種。ランタイムのローカル状態バックエンドでユーザーが状態を読み取るときはディスクを経由するため、状態をディスクに維持することになる。それに伴うコストは、状態を読み取るたびにシリアライズとデシリアライズのプロセスを経る必要があり、性能は相対的に劣る可能性がある。
イベント時間処理#
処理時間(Processing Time)
: プロセスタイムは、イベントが到着してから処理を開始する時間であり、必ずしも一定ではない。例えば、ネットワークの理由でこの時間が変わることがある。イベント時間(Event Time)
: イベント時間は、イベントが実際に発生した時間であり、各処理記録が持つタイムスタンプに基づいて判断される。これは唯一で不変である。接入時間(Ingestion Time)
: イベントがソースオペレーターで Flink データストリームに入る時間を指す。
対比
- 処理時間は扱いやすいが、イベント時間はより複雑である。
- 処理時間を使用する場合、得られる処理結果(またはストリーム処理アプリケーションの内部状態)は不確定である。しかし、Flink 内部でイベント時間に対してさまざまな保障が行われているため、イベント時間を使用する場合、データを何度再生しても、相対的に確定的で再現可能な結果を得ることができる。
- 処理時間を使用するかイベント時間を使用するかを判断する際には、次の原則に従うことができる:アプリケーションが前のチェックポイントまたはセーブポイントから再生する際に、結果が完全に同じであることを望むかどうか。結果が完全に同じであることを望む場合は、イベント時間を使用する必要がある。結果が異なることを受け入れる場合は、処理時間を使用できる。処理時間の一般的な用途は、現実の時間に基づいてシステム全体のスループットを統計することである。例えば、現実の時間で 1 時間に何件のデータを処理したかを計算する場合、この状況では処理時間を使用する必要がある。
参考リンク
状態保存と移行#
Savepoint メカニズムに基づいて実現され、Savepoint はチェックポイントに似ているが、異なる点は Savepoint は手動でトリガーされ、全体の状態保存に使用される。具体的な参考リンク:
Flink リアルタイム計算 - チェックポイントとセーブポイントの深い理解
Flink 基本概念#
-
Streams
: ストリームは有限データストリームと無限データストリームに分かれ、unbounded stream
は始まりも終わりもないデータストリーム、すなわち無限データストリームである。一方、bounded stream
はサイズが制限された始まりと終わりのあるデータ集合、すなわち有限データストリームであり、両者の違いは無限データストリームのデータは時間の推移とともに増加し続け、計算が継続し、終了状態が存在しないのに対し、有限データストリームはデータサイズが固定され、計算が最終的に完了し、終了状態にあることである。 -
State
: 状態は計算プロセス中のデータ情報であり、フォールトトレランス回復とチェックポイントにおいて重要な役割を果たす。ストリーム計算は本質的にインクリメンタル処理であるため、状態を維持するために継続的にクエリを行う必要がある。また、正確に一度のセマンティクスを確保するために、データが状態に書き込まれる必要がある。持続的なストレージは、分散システム全体が故障またはダウンした場合でも正確に一度を保証することができ、これは状態のもう一つの価値である。 -
Time
:Event time
、Ingestion time
、Processing time
に分かれ、Flink の無限データストリームは継続的なプロセスであり、時間はビジネスの状態が遅れているか、データ処理がタイムリーであるかを判断する重要な基準である。 -
API
: API は通常 3 層に分かれ、上から下に分けるとSQL / Table API
、DataStream API
、ProcessFunction
の 3 層である。API の表現能力とビジネス抽象能力は非常に強力であるが、SQL 層に近づくにつれて表現能力は徐々に弱まり、抽象能力は強化される。逆に、ProcessFunction 層の API の表現能力は非常に強く、さまざまな柔軟で便利な操作が可能であるが、抽象能力は相対的に小さい。
Flink ウィンドウ#
- イベント数に基づくカウントウィンドウ
- セッション間隔に基づくセッションウィンドウ
- 時間に基づくタイムウィンドウ