1. ステータスとは
ステートレス計算の例:たとえば、初めて加算演算子を入力すると、2+3=5
今後複数回データを入力した2+3
ときに同じ結果が得られます5
。結論としては、同じ入力は回数に関係なく同じ結果が得られます。
ステートフル コンピューティングの例:訪問の統計:Nginx
アクセス ログにはリクエストごとに 1 つのログがあることは誰もが知っています。これに基づいて訪問をカウントできます。以下に示すように、/api/a
最初url
の訪問では返される結果は ですcount1
が、2 回目の訪問では返される結果は になります2
。Flink
以前に一度処理されたことがあるのはなぜですかhello world
? ここで問題が発生します。前にカウントする必要があるデータを保存するstate
ために呼び出されます。インターフェイスの呼び出しにより、除算用のペアが作成されます。これは、次の前提条件です。使用。結論としては、同じ入力でも異なる結果が得られ、これは回数に関係します。これはステートフルなデータです。keyed state
keyby
keyed stream
key
keyed state
この種のステータス データはどのようなシナリオで大量に使用されるのでしょうか? いくつか例を挙げてみましょう:
[1]重複を削除する必要がある場合、たとえば、100
この
【2】ウィンドウ計算、未トリガーデータが入力されました。たとえば、統計は 1 分に 1 回カウントされますが、1-2
その結果が関連しているため、1.5
この時点のデータは2
ステートフル データとなります。【3】機械学習/深層学習、学習済みモデルとパラメータ。これは機械学習の学生にとって深い印象です。たとえば、初めて を入力すると、マシンはフィードバックを返し、次回はこのフィードバックに基づいてさらなる学習と処理を行います。前のステップの結果は、私へのステートフルな入力になります。【4】過去のデータにアクセスするには、昨日と比較する必要があります。昨日のデータは今日の状態でもあります。じっくり味わって味わってください。2
1.5
hello
なぜ状態管理が必要なのでしょうか? メモリを使用するのは良いことではないでしょうか? まず、チャーン操作には独自の基準があり、単にチャーン処理と言えるものではありません。まず、24時間365日稼働しており信頼性が高いですが、メモリが少ないといずれ容量を使い果たしてしまいます。第二に、データが失われていない場合、データは重くなりませんが、一度だけ計算された場合、メモリのバックアップと復元が必要になり、常にデータのごく一部の損失が伴います。最後に、データは遅延なくリアルタイムに生成されますが、メモリが足りない場合は水平展開を遅らせる必要があります。
理想的な状態管理は以下で説明するものであり、Flink
私たちはそれを実現しています。
2. ステータスの種類
管理された状態と生の状態
管理された状態 | 生の状態 | |
---|---|---|
ステータス管理方法 | Flink ランタイム管理 - 自動ストレージ、自動リカバリ - 最適化されたメモリ管理 | ユーザーが自分で管理します (Flink は State に保存したデータ構造を知りません) - 自分でインスタンス化する必要があります |
ステータスデータ構造 | 既知のデータ構造 - 値、リスト、マップなど | バイトデータ—byte[] |
推奨される使用シナリオ | ほとんどの場合に使用できます | Operator をカスタマイズするときに使用できます (管理状態が十分でない場合に使用) |
Managed Stated は、次の Keyed Stated
ものとOperator State
[1] Keyed Stated:keyBy
生成にのみ使用できるKeyedStream
演算子に分かれています。それぞれがkey
1 つに対応しState
、1 つのOperator
インスタンスが複数の を処理しKey
、対応する複数の にアクセスしますState
。同じものはKey
同じインスタンスで処理されます。keyBy
プロセス全体に操作がなければ無駄でありKeyedStream
、Keyed Stated
適用することしかできませんKeyedStream
。
同時変更: State
インスタンス間での移行時Key
。たとえば、インスタンス内で との前をA
処理し、その後 インスタンス を拡張すると、インスタンスは処理するだけで済み、処理のためにインスタンスに渡されます。設置状況が分離されており、分散していることが分かります。KeyA
KeyB
B
A
KeyA
KeyB
B
RuntimeContext を通じてアクセスされる場合、説明はOperator
1 つですRich Function
が、それ以外の場合は取得できませんRuntimeContext
。
サポートされているデータ構造: ValueState
、ListState
、ReducingState
、AggregatingState
、MapState
【2】演算子の状態:すべての演算子に使用できます。source
たとえば、 でよく使用されますFlinkKafkaConsumer
。1 つのOperator
インスタンス は 1 つの インスタンス に対応するState
ため、Operator
複数の インスタンス は 1 つの インスタンス で処理されkey
、クラスターとして理解できます。
同時変更: Operator State
いいえkey
、同時変更が発生した場合は再割り当てが必要です。均等配分と全額を取得するための結合という 2 つの組み込みソリューションがあります。
アクセス方法:実装CheckpointedFunction
またはListCheckpointed
インターフェイス。
サポートされているデータ構造: ListState
3. Keyed Stateの使用例
キー付き状態とは:にはkeyed state
2 つの特性があります: [1] KeyedStream の関数と操作(例: )
にのみ適用できます; [2]パーティション化/分割されており、各キーは にのみ属することができます。特定のキー付き状態. ;パーティショニングの概念を理解するには、セマンティクスを確認する必要があります。下の図の左側に 3 つの同時実行性があり、右側にも 3 つの同時実行性があることがわかります。左の言葉が入ってきたら、それに応じて分配されます。たとえば、この単語は常に右下に移動し、同時に上に移動します。Keyed UDF
window state
keyed state
keyby
keyby
hello word
hello
hash
task
オペレーター状態とは
[1] とも呼ばれnon-keyed state
、それぞれはoperator state
1 つのインスタンスのみにバインドされますoperator
。
【2】一般的な例operator state
は、source state
現在のコードを記録してsource
から、使用されているコードoffset
の一部を確認することです。operator state
word count
ここでfromElements
呼び出されるクラスはFromElementsFunction
の型を使用しlist state
ますoperator state
。次のタイプKeyed State
間の依存関係はすべて のstate
サブクラスです。それらのアクセス方法とデータ構造には特定の違いがあります。
ステータスのデータ型 | アクセスインターフェース | 述べる | |
---|---|---|---|
値の状態 | 単一の値 | [更新(T)変更/T値取得] | たとえば、WordCount は word をキーとして使用し、state は単一の値です。この単一項目は文字列やオブジェクトなどにすることも可能です。アクセスする方法は 2 つだけです。 |
地図の状態 | 地図 | put(UK キー, UV 値) putAll(Map<UK,UV> マップ) Remove(UK キー) boolean contains(UK キー) UV get(UK キー) Iterable<Map.Entry> エントリ() Iterable<Map.Entry> iterator() 反復可能なキー() 反復可能な値() | 特定のオブジェクトを操作できるキー |
リスト状態 | リスト | add/ addAll(List) update(List) Iterable get() | |
還元状態 | 単一の値 | add/ addAll(List) update(List) T get() | List と同じ親クラスであり、この追加により、Reducing 結果にデータが直接更新されます。たとえば、1 分間の結果をカウントする場合、最初にデータがリストに追加され、1 分後にすべてのデータがカウントされます。削減すると、結果ごとに 1 つの結果がカウントされます。利点はメモリを節約できることです。 |
集約状態 | 単一の値 | add(IN)/OUT get() | Listと同じ親クラスですが、Reducingとの違いは入力と出力の型が同じであることです。集約は異なる場合があります。たとえば、タイの値を計算したい場合、Reducing では計算結果が返され、Aggregating では合計と数値が返されます。 |
ValueState
ケースを与える
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//获取数据流
DataStream<Event> events = env.addSource(source);
DataStream<Alert> alerts = events
// 生成 keyedStata 通过 sourceAddress
.keyBy(Event::sourceAddress)
// StateMachineMapper 状态机
.flatMap(new StateMachineMapper());
//我么看下状态机怎么写 实现 RichFlatMapFunction
@SuppressWarnings("serial")
static class StateMachineMapper extends RichFlatMapFunction<Event, Alert> {
private ValueState<LeaderLatch.State> currentState;
@Override
public void open(Configuration conf) {
// 获取一个 valueState
currentState = getRuntimeContext().getState(
new ValueStateDescriptor<>("state", State.class));
}
//来一条数据处理一条
@Override
public void flatMap(Event evt, Collector<Alert> out) throws Exception {
// 获取 value
State state = currentState.value();
if (state == null) {
state = State.Initial;//State 是本地的变量
}
// 把事件对状态的影响加上去,得到一个状态
State nextState = state.transition(evt.type());
//判断状态是否合法
if (nextState == State.InvalidTransition) {
//扔出去
out.collect(new Alert(evt.sourceAddress(), state, evt.type()));
}
//是否不能继续转化了,例如取消的订单
else if (nextState.isTerminal()) {
// 从 state 中清楚掉
currentState.clear();
}
else {
// 修改状态
currentState.update(nextState);
}
}
}
4. CheckPoint と状態の関係
Checkpoint
これは、トリガーからすべての下流ノードの完了までのグローバル操作ですsource
。次の図は、正しい直観的な感覚を与えることができます。赤いボックス内で、合計で 2回トリガーされ、すべてが正常に完了したことCheckpoint
がわかります。そのようなことはありません。569K
Checkpoint
fail
**状態は実際には、チェックポイントによって作成されたメイン永続バックアップのメイン データです。**下の図の特定のデータ統計を見てください。これはサイズstate
でもあります。9kb
5. ステータスの保存と復元方法
Checkpoint
定期的に分散スナップショットを作成して、プログラムの状態をバックアップします。失敗した場合は、ジョブ全体をTask
最後に成功したCheckpoint
状態にロールバックし、保存された時点から処理を続行します。
必要な条件:データ ソースが再送信をサポートしている (再送信しない場合、失われたメッセージは実際に失われます)
一貫性セマンティクス:少なくとも 1 回 (p
同じ、単一スレッド、複数スレッドの場合、一部の演算子は一度計算され、一部の演算子は一度計算されていない可能性があるため、注意する必要があります)。
// 获取运行环境
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
//状态数据
//两个checkpoint 触发间隔设置1S,越频繁追的数据就越少,io消耗也越大
env.enableCheckpointing(1000);
//EXACTLY_ONCE语义说明 Checkpoint是要对替的,这样消息不会重复,也不会对丢。
env.getCheckpointConfig().setCheckpointingMode(CheckpointingMode.EXACTLY_ONCE);
//两个checkpoint 最少等待500ms 例如第一个checkpoint做了700ms按理300ms后就要做下一个checkpoint。但是它们之间的等待时间300ms<500ms 此时,就会延长200ms减少checkpoint过于频繁,影响业务。
env.getCheckpointConfig().setMinPauseBetweenCheckpoints(500);
//checkpoint多久超时,如果这个checkpoint在1分钟内还没做完,那就失败了
env.getCheckpointConfig().setCheckpointTimeout(60000);
//同时最多有多少个checkpoint进行
env.getCheckpointConfig().setMaxConcurrentCheckpoints(1);
//当重新分配并发度,拆分task时,是否保存checkpoint。如果不保存就需要使用savepoint来保存数据,放到外部的介质中。
env.getCheckpointConfig().enableExternalizedCheckpoints(CheckpointConfig.ExternalizedCheckpointCleanup.DELETE_ON_CANCELLATION);
チェックポイントとセーブポイント
チェックポイント | セーブポイント | |
---|---|---|
トリガー管理方法 | Flink によって自動的にトリガーおよび管理されます | ユーザーによって手動でトリガーおよび管理されます |
主目的 | ネットワークジッターによるタイムアウト例外など、タスク例外が発生した場合に迅速に回復します。 | コードの変更や同時実行性の調整などのジョブを停止して再開できるように、計画的なバックアップを実行します。 |
特徴 | 軽量、障害から自動的にサービスされ、ジョブの停止後にデフォルトでクリアされる | 耐久性があり、標準形式で保存されるため、コードまたは構成の変更によりセーブポイントのリカバリを手動でトリガーできます。 |
オプションの状態保存方法:
[1] MemoryStateBackend
: 構築方法:
MemoryStateBackend(int maxStateSize, boolean asynchronousSnapshots)
保存方法: State
:TaskManager
メモリ。Checkpoint
:JobManager
メモリ。
容量制限:State maxStateSize
デフォルトは 1 つです5M
。maxStateSize <= akka.framesize
デフォルト10M
。合計サイズがJobManager
メモリを超えることはありません。
推奨される使用シナリオ:ETL/JobManager
ローカル テスト、ほぼステートレスなジョブ (ハングしにくい状況や影響がほとんどない状況など) 。運用シナリオでの使用はお勧めしません。
【2】FsStateBackend:構築方法:
FsStateBackend(URL checkpointDataUri, boolean asynchronousSnapshots)
保存方法: State
:TaskManager
メモリ。Checkpoint
: 外部ファイル システム (ローカルまたはHDFS
)。
容量制限:単一TaskManager
デバイスの合計容量はState
、そのメモリを超えません。合計サイズは、構成されたファイル システムの容量を超えません (定期的にクリーンアップされます)。
推奨される使用シナリオ:分単位のウィンドウ集計など、通常の使用状況のジョブjoin
。開始する必要があるジョブHA
。実稼働環境でも使用できます。
【3】RocksDBStateBackend:構築方法:
RocksDBStateBackend(URL checkpointDataUri, boolean enableIncrementalCheckpointing)
保存方法: State
:TaskManager
データベースKV
(メモリ + ディスクの実使用量)。Checkpoint
: 外部ファイル システム (ローカルまたはHDFS
)。
容量制限:単一TaskManager
デバイスの合計容量は、単一デバイスの最大値であるState
メモリ + ディスクを超えません。合計サイズは、構成されたファイル システムの容量を超えません。推奨される使用シナリオ:日レベルのウィンドウ集計など、非常に大きなステータスを持つジョブ。開始する必要があるジョブ。比較的高いステータスの読み取りおよび書き込みパフォーマンスを必要とするジョブ。実稼働環境でも使用できます。key
2G
HA