Flinkはクラシックコース4を知っている必要があります:Flinkのフォールトトレランス

はじめに: この記事は、アリババのシニアテクニカルエキスパートであるLiYuのApacheFlink PMCによって共有されています。主に、ステートフルストリームコンピューティング、グローバルに整合性のあるスナップショット、Flinkのフォールトトレランスメカニズム、Flinkの状態管理の4つの側面からFlinkのフォールトトレランスメカニズムの原理を紹介しています。

著者|李煜

共有者:この記事は、AlibabaのシニアテクニカルエキスパートであるLiYuのApacheFlink PMCが共有しています。主に、Flinkのフォールトトレランスメカニズムの原理を紹介しています。内容の概要は次のとおりです。

  1. ステートフルストリームコンピューティング
  2. グローバルに一貫したスナップショット
  3. Flinkのフォールトトレランスメカニズム
  4. Flinkの状態管理

1.ステートフルストリームコンピューティング

ストリームコンピューティング

Slide04.png

ストリームコンピューティングとは、メッセージを継続的に送信できるデータソースがあり、同時にコードを実行する常駐プログラムがあることを意味します。データソースからメッセージを受信した後、それを処理し、結果をに出力します。下流。

分散ストリームコンピューティング

スライド05.png

分散ストリームコンピューティングとは、入力ストリームを特定の方法で分割し、複数の分散インスタンスを使用してストリームを処理することです。

ストリームコンピューティングの状態

スライド06.png

コンピューティングはステートフルとステートレスに分けることができます。ステートレスコンピューティングは単一のイベントを処理するだけでよく、ステートフルコンピューティングは複数のイベントを記録して処理する必要があります。

簡単な例を挙げてください。たとえば、イベントは、イベントIDとイベント値の2つの部分で構成されます。処理ロジックが、イベントが取得されるたびにそのイベント値を解析して出力する場合、これはステートレス計算です。逆に、毎回状態を取得し、その値を解析した後、前のイベント値と比較する必要があり、前のイベント値よりも大きい場合にのみ出力されます。これはステートフル計算です。

スライド07.png

ストリームコンピューティングには多くの状態があります。たとえば、重複排除シナリオでは、すべてのプライマリキーが記録されます。または、ウィンドウ計算では、ウィンドウに入ったがトリガーされていないデータは、ストリームコンピューティングの状態でもあります。機械学習/ディープラーニングシナリオでは、 、トレーニング済みモデルおよびパラメータデータはストリームコンピューティングの状態です。

2.グローバルに一貫性のあるスナップショット

グローバルに整合性のあるスナップショットは、分散システムのバックアップと障害回復に使用できるメカニズムです。

グローバルスナップショット

グローバルスナップショットとは

スライド11.png

グローバルスナップショットは、最初に複数のサーバーに分散された複数のプロセスを持つ分散アプリケーションです。次に、アプリケーション内に独自の処理ロジックと状態があります。3番目に、アプリケーションは相互に通信できます。4番目に、この種の分散アプリケーションには内部があります。状態とハードウェアは通信できます。ある時点でのグローバル状態は、グローバルスナップショットと呼ばれます。

グローバルスナップショットが必要な理由

スライド12.png

  • まず、これをチェックポイントとして使用します。定期的にグローバル状態をバックアップできます。アプリケーションに障害が発生した場合は、復元に使用できます。
  • 次に、デッドロック検出を実行します。スナップショットが作成された後、現在のプログラムは引き続き実行されます。次に、スナップショットを分析して、アプリケーションがデッドロック状態にあるかどうかを確認し、デッドロック状態にある場合はそれに応じて処理できます。

グローバルスナップショットの例

次の図は、分散システムのグローバルスナップショットの例です。

スライド16.png

P1とP2は2つのプロセスであり、C12とC21の間にメッセージを送信するためのパイプがあります。P1プロセスの場合、C12は出力チャネルと呼ばれるメッセージを送信するチャネルであり、C21は入力チャネルと呼ばれるメッセージを受信するチャネルです。

パイプを除いて、すべてのプロセスにはローカル状態があります。たとえば、P1とP2の各プロセスのメモリには、3つの変数XYZと対応する値があります。次に、P1プロセスとP2プロセスのローカル状態、およびそれらの間でメッセージを送信するためのパイプライン状態が初期グローバル状態になります。これは、グローバルスナップショットとも呼ばれます。

スライド17.png

P1がメッセージをP2に送信し、P2にxの状態値を4から7に変更するように要求したが、このメッセージはパイプラインにあり、まだP2に到達していないとします。この状態は、グローバルスナップショットでもあります。

スライド18.png

次に、P2はP1からメッセージを受信しましたが、まだ処理されていません。この状態もグローバルスナップショットです。

スライド19.png

最後に、メッセージを受信したP2は、ローカルXの値を4から7に変更しました。これは、グローバルスナップショットでもあります。

したがって、イベントが発生すると、グローバル状態が変化します。イベントには、メッセージを送信するプロセス、メッセージを受信するプロセス、および自身の状態を変更するプロセスが含まれます。

2.グローバルに一貫性のあるスナップショット

スライド20.png

絶対時間でaとbの2つのイベントがあり、bとbがスナップショットに含まれる前にaが発生した場合、aもスナップショットに含まれます。この条件を満たすグローバルスナップショットは、グローバル整合性スナップショットと呼ばれます。

2.1グローバルに整合性のあるスナップショットの実装方法

スライド22.png

クロック同期はグローバル整合性スナップショットを実現できません。グローバル同期は実現できますが、その欠点も非常に明白です。すべてのアプリケーションが停止し、グローバルパフォーマンスに影響します。

3.非同期グローバル整合性スナップショットアルゴリズム– Chandy-Lamport

非同期のグローバル整合性スナップショットアルゴリズムChandy-Lamportは、アプリケーションの動作に影響を与えることなく、グローバル整合性のあるスナップショットを実現できます。

Chandy-Lamportのシステム要件は次のとおりです。

  • まず、アプリケーションの動作には影響しません。つまり、メッセージの送受信には影響せず、アプリケーションを停止する必要はありません。
  • 次に、各プロセスはローカル状態を記録できます。
  • 第三に、記録された状態を分散して収集することができます。
  • 第4に、どのプロセスでもスナップショットを開始できます

同時に、Chandy-Lamportアルゴリズムを実行できるという別の前提条件があります。メッセージは整然としていて繰り返しがなく、メッセージの信頼性が保証されます。

3.1Chandy-Lamportアルゴリズムフロー

スライド24.png

Chandy-Lamportのアルゴリズムフローは、主に3つの部分に分かれています。スナップショットの開始、分散実行スナップショット、スナップショットの終了です。

スナップショットを開始します

どのプロセスでもスナップショットを開始できます。次の図に示すように、P1がスナップショットを開始するとき、最初のステップはローカル状態を記録することです。つまり、ローカルのスナップショットを取得し、すぐにすべての出力チャネルにマーカーメッセージを送信します。間の時間ギャップ。マーカーメッセージは、アプリケーション間で渡されるメッセージとは異なる特別なメッセージです。

スライド25.png

マーカーメッセージを送信した後、P1は入力チャネルのすべてのメッセージの記録を開始します。これは、図に示されているC21パイプラインのメッセージです。

分散実行スナップショット

次の図に示すように、最初に、PiがCkiからマーカーメッセージを受信したとき、つまり、PkからPiに送信されたマーカーメッセージを想定します。それは2つの状況で見ることができます:

スライド26.png

最初のケース:これは、Piが他のパイプから受信した最初のマーカーメッセージです。最初にローカル状態を記録し、次にC12パイプを空としてマークします。つまり、メッセージが後でP1から送信された場合、次のようになります。このスナップショットには含まれていませんが、同時に、すべての出力チャネルにマーカーメッセージをすぐに送信します。最後に、Ckiを除くすべての入力チャネルからのメッセージの録音を開始します。

スライド27.png

前述のように、Ckiメッセージはリアルタイムスナップショットに含まれていませんが、リアルタイムメッセージは引き続き発生するため、2番目のケースは、Piが以前にマーカーメッセージを受信したことがある場合、Ckiメッセージの記録を停止し、すべてを記録することです。以前に記録されたCkiメッセージ。メッセージは、このスナップショットにCkiの最終状態として保存されます。

スナップショットを終了します

スナップショットを終了するには、次の2つの条件があります。

  • まず、すべてのプロセスがマーカーメッセージを受信し、ローカルスナップショットに記録しました。
  • 次に、すべてのプロセスがn-1個の入力チャネルからマーカーメッセージを受信し、パイプラインのステータスを記録しました。

スライド28.png

スナップショットが終了すると、スナップショットコレクター(中央サーバー)はスナップショットの各部分の収集を開始して、グローバルに整合性のあるスナップショットを形成します。

サンプル表示

次の図の例では、他のプロセスと相互作用しないAなど、一部の状態が内部で発生します。内部状態は、P1がそれ自体にメッセージを送信することであり、AはC11 = [A->]と考えることができます。

スライド29.png

Chandy-Lamportのグローバルに一貫性のあるスナップショットアルゴリズムはどのように実装されていますか?

スライド30.png

スナップショットがp1から開始されたとします。スナップショットを開始すると、最初にS1と呼ばれるローカル状態のスナップショットを取得し、すぐにすべての出力チャネル、つまりP2とP3にマーカーメッセージを送信してから、記録します。入力チャネルのメッセージは、P2とP3およびそれ自体からのメッセージです。

スライド31.png

凡例に示されているように、縦軸は絶対時間ですが、絶対時間によると、マーカーメッセージを受信したときにP3とP2の間に時間差があるのはなぜですか?これが実際の物理環境での分散プロセスである場合、異なるノード間のネットワーク条件が異なり、メッセージ配信時間の違いにつながるためです。

P3は最初にマーカーメッセージを受信し、それが最初に受信するマーカーメッセージです。メッセージを受信した後、最初にローカル状態のスナップショットを取得し、次にC13パイプラインをクローズとしてマークし、同時にすべての出力チャネルへのマーカーメッセージの送信を開始し、最後にすべての入力からすべての入力チャネルを送信しますC13以外のチャンネルメッセージの録音が始まります。

Slide32.png

P3から送信されたマーカー情報を受信するのはP1ですが、これが最初に受信するマーカーではありません。C31チャネルからパイプラインをすぐに閉じ、現在のレコードメッセージをこのチャネルのスナップショットとして取得してから受信します。 P3のニュースは、このスナップショット状態では更新されません。

スライド33.png

次に、P2はP3からメッセージを受信します。これは、最初に受信するマーカーメッセージです。メッセージを受信した後、最初にローカル状態のスナップショットを取得し、次にC32パイプラインをクローズとしてマークし、同時にすべての出力チャネルへのマーカーメッセージの送信を開始し、最後にすべての入力チャネルのスナップショットを取得しますC32を除くメッセージの録音が始まります。

スライド34.png

P1からメッセージを受信するP2を見てみましょう。これはP2が受信する最初のマーカーメッセージではないため、すべての入力チャネルを閉じ、チャネルのステータスを記録します。

スライド35.png

次に、P1がP2からメッセージを受信することを確認しましょう。これは、P2が受信する最初のメッセージではありません。次に、すべての入力チャンネルを閉じ、録音されたメッセージをステータスとして使用します。次に、2つの状態があります。1つは自分自身に送信されるメッセージであるC11であり、もう1つはP2のHによってP1Dに送信されるC21です。

スライド36.png

最後の時点で、P3はP2からメッセージを受信しますが、これは最初に受信するメッセージではなく、操作は上記と同じです。この期間中、P3はローカルでイベントJを持ち、その状態としてJも取ります。

スライド37.png

すべてのプロセスがローカル状態を記録し、各プロセスのすべての入力パイプが閉じられると、グローバル整合性スナップショットが終了します。つまり、過去の時点のグローバル状態の記録が完了します。

3.3チャンディ・ランポートとフリンクの関係

Flinkは分散システムであるため、Flinkはグローバルに整合性のあるスナップショットを使用してチェックポイントを形成し、障害回復をサポートします。Flinkの非同期のグローバル整合性スナップショットアルゴリズムとChandy-Lamportアルゴリズムの主な違いは次のとおりです。

  • まず、Chandy-Lamputは強く接続されたグラフをサポートし、Flinkは弱く接続されたグラフをサポートします。
  • 次に、Flinkは、調整された(調整された)Chandy-Lamput非同期スナップショットアルゴリズムを使用します。
  • 第3に、Flinkの非同期スナップショットアルゴリズムは、DAGシナリオでチャネル状態を保存する必要がないため、スナップショットのストレージスペースが大幅に削減されます。

3つ目は、Flinkのフォールトトレランスメカニズムです。

スライド40.png

フォールトトレランスとは、エラーが発生する前の状態に復元することを意味します。ストリームコンピューティングのフォールトトレラントな整合性保証には、次の3つのタイプがあります。正確に1回、少なくとも1回、最大で1回。

  • 正確に1回とは、各イベントが状態に1回だけ影響を与えることを意味します。ここでの「1回」は、エンドツーエンドの厳密なものではなく、ソースとシンクの処理を除く、Flink内の1つの処理のみです。
  • 少なくとも1回は、各イベントが少なくとも1回は状態に影響を与えることを意味します。つまり、処理が繰り返される可能性があります。
  • 最大で1回とは、各イベントが最大で1回状態に影響を与えることを意味します。つまり、エラーが発生すると状態が失われる可能性があります。

エンドツーエンドで1回だけ

正確に1回とは、ジョブの結果が常に正しいことを意味しますが、複数回生成される可能性が高いため、再生可能なソースが必要です。
エンドツーエンド正確に1回とは、ジョブの結果が正しく、1回だけ出力されることを意味します。再生可能なソースに加えて、トランザクションシンクとべき等の出力結果を受信する機能も必要です。

Flinkの状態フォールトトレランス

多くのシナリオでは、正確に1回のセマンティクスが必要です。つまり、処理して1回だけ処理する必要があります。セマンティクスを確保する方法は?

単純なシナリオでのフォールトトレラントな方法

簡単なシナリオは次の図に示すとおりです。方法は、ローカル状態を記録し、ソースのオフセット、つまりイベントログの場所を記録することです。

スライド43.png
スライド44.png
Slide45.png

分散シナリオでのフォールトトレランスの状態

分散シナリオの場合、操作を中断することなく、ローカル状態を持つ複数のオペレーターのグローバルに一貫したスナップショットを生成する必要があります。Flink分散シーンのジョブトポロジは特別です。これは、有向非巡回で弱く接続されたグラフです。調整されたChandy-Lamportを使用できます。つまり、すべての入力オフセットと各演算子の状態のみを記録し、に依存します。巻き戻し可能なソース(バックトラッキングソースはオフセットを介して少し早く読み取ることができます)であるため、チャネルの状態を保存する必要はありません。これにより、集約ロジックが存在する場合に多くのストレージスペースを節約できます。

スライド49.png

最後に、復元とはデータソースの場所をリセットすることであり、各オペレーターはチェックポイントから状態を復元します。

3.Flinkの分散スナップショット方式

スライド50.png

まず、ソースデータストリームにチェックポイントバリアを挿入します。これは、上記のチャンディランポートアルゴリズムのマーカーメッセージです。チェックポイントバリアが異なると、ストリームが自然に複数のセグメントに分割され、各セグメントにチェックポイントデータが含まれます。

スライド51.png

Flinkにはグローバルコーディネーターがいます。任意のプロセスのスナップショットを開始できるChandy-Lamportとは異なり、この集中型コーディネーターは各ソースにチェックポイントバリアを挿入してから、スナップショットを開始します。各ノードがバリアを受信すると、チャネル状態をFlinkに保存しないため、ローカル状態を保存するだけで済みます。

Slide52.png

チェックポイントが完了すると、各オペレーターの同時実行ごとに確認メッセージがコーディネーターに送信されます。すべてのタスクの確認メッセージがチェックポイントコーディネーターによって受信されると、スナップショットは終了します。

4.プロセスのデモンストレーション

次の図に示すように、チェックポイントNがソースに挿入されると、ソースは最初に処理中のパーティションのオフセットを記録します。

スライド53.png

時間の経過とともに、チェックポイントバリアを2つの同時ダウンストリームに送信します。バリアが2つの同時実行に達すると、2つの同時実行はそれぞれローカル状態をチェックポイントに記録します。

最後に、バリアが最後のサブタスクに到達し、スナップショットが完成します。

スライド54.png

これは比較的単純なシナリオのデモンストレーションです。各オペレーターには単一の入力ストリームしかありません。次の図のより複雑なシナリオを見てみましょう。ここでは、オペレーターに複数の入力ストリームがあります。

スライド62.png

オペレーターが複数の入力を持っている場合、バリアを調整する必要があります。バリアを調整する方法は?下の図に示すように、左の元の状態では、一方のバリアが到着したときに、もう一方のバリアコマンドの一部のバリアがパイプラインに到着していません。この時点で、最初に到着したフローは正確であることが保証されます。直接ブロックしてから、別のストリームのデータ処理を待ちます。別のストリームが到着すると、前のストリームのブロックが解除され、同時にバリアがオペレーターに送信されます。

スライド67.png

このプロセスでは、ストリームの1つをブロックすると、背圧が発生します。バリアの位置合わせにより背圧が発生し、オペレーターのデータ処理が中断されます。

バリアを受信したデータパイプラインがアライメントプロセス中にブロックされず、データが引き続き流入する場合、次のチェックポイントに属するデータが現在のチェックポイントに含まれます。障害が発生すると、ソースが巻き戻されます。 、およびデータの一部が巻き戻されます。少なくとも1回の繰り返し処理が行われます。少なくとも1回は受け取ることができる場合は、バリアの調整を回避できる他の副作用を選択できます。さらに、非同期スナップショットを使用して、タスクのストールを最小限に抑え、同時に複数のチェックポイントをサポートすることもできます。

5.スナップショットトリガー

スライド69.png

システムへのローカルスナップショットの同期アップロードには、状態のコピーオンライトメカニズムが必要です。

メタデータ情報のスナップショットの後にデータ処理が復元された場合、復元されたアプリケーションロジックが、データのアップロードプロセス中にアップロードされているデータを変更しないようにするにはどうすればよいですか?実際、さまざまな状態のストレージバックエンドの処理は異なります。ヒープバックエンドはデータのコピーオンライトをトリガーします。RocksDBバックエンドの場合、LSM機能により、スナップショットされたデータが変更されないようにすることができます。

スライド70.png

第四に、フリンクの状態管理

1.フリンクステータス管理

スライド73.png

まず、状態を定義する必要があります。以下の例では、最初に値の状態を定義します。

ステータスを定義するときは、次の情報を提供する必要があります。

  • ステータス識別ID
  • ステータスデータ型
  • ローカルステータスバックエンド登録ステータス
  • ローカルステータスバックエンドの読み取りおよび書き込みステータス

2.フリンクステータスバックエンド

状態バックエンドとも呼ばれ、2つのFlink状態バックエンドがあります。

Slide77.png

  • 最初のタイプであるJVMヒープ、その中のデータはJavaオブジェクトの形式で存在し、読み取りと書き込みもオブジェクトの形式で行われるため、速度は非常に高速です。ただし、2つの欠点もあります。1つ目の欠点は、オブジェクトストレージに必要なスペースが、ディスク上のシリアル化および圧縮されたデータのサイズの何倍にもなるため、多くのメモリスペースを占有することです。2つ目の欠点は、読み取りと書き込みですが、シリアル化を行う必要はありませんが、スナップショットを作成するときにシリアル化する必要があるため、非同期スナップショットプロセスは遅くなります。

Slide80.png

  • 2番目のタイプはRocksDBです。このタイプは、読み取りと書き込みの際にシリアル化する必要があるため、読み取りと書き込みの速度は比較的遅くなります。ただし、LSMベースのデータ構造はスナップショットの後にsstファイルを形成するという利点があります。その非同期チェックポイントプロセスはファイルコピーのプロセスであり、CPU消費量は比較的低くなります。

おすすめ

転載: blog.csdn.net/weixin_43970890/article/details/115011836