flink之OperatorState(非キー状態)

flinkによると、flinkはすべてのオペレーターのステートフルコンピューティングをサポートしています。ブロガーが共有する記事では、キー付き状態が詳細に紹介されており、愛好家はhttps://blog.csdn.net/qq_44962429 / article / detailsをクリックしてください。 / 104428236 AC

通常の本番環境では、キー状態のアプリケーションが増えていますが、Windowsをベースに外部システムに出力する必要がある場合は、データを失わないように、または外部システムに繰り返し出力するために、シンクオペレーターも状態を保存する必要があります。次に、この記事では主にオペレーターの状態を紹介します

1、オペレーターの状態

ユーザーがOperatorStateを使用する場合は、共通のCheckpointedFunctionインターフェイスまたはを実装するListCheckpointed<T extends Serializable>だけで済みます。現在のoperator-stateはリストスタイルの状態のみをサポートし、格納されている状態はListである必要があり、その中の要素はListである必要があります。シリアル化できます。

(1)チェックポイント機能

CheckpointedFunctionは、2つの異なる状態分散スキームを提供します。Even-splitおよびUnion、インターフェイスは2つのメソッドを提供します。

均等分割:システムが障害から回復すると、オペレーター状態の要素がすべてのオペレーターインスタンスに均等に分散され、各オペレーターインスタンスがオペレーター状態全体のサブリストデータを取得することを示します。

連合:システムが障害から回復しているときに、各オペレーターインスタンスがオペレーター状態全体のすべてのデータを取得できることを示します。

void snapshotState(FunctionSnapshotContext context) throws Exception;
void initializeState(FunctionInitializationContext context) throws Exception;
  • snapshotState():呼び出されるcheckpoint()と、システムはsnapshotState()状態のスナップショットを取得するために呼び出します
  • initializeState():システムは、最初に起動されたとき、または最後の状態から復元されたときに呼び出しますinitializeState()

例:wordCount統計を実行し、統計が特定のデータしきい値に達した場合にのみ、次のオペレーターまたは周辺システムに出力します。

class BufferingSink(threshold: Int = 0) extends SinkFunction[(String, Int)]  with CheckpointedFunction  {
    
    
    var listState:ListState[(String,Int)]=_
    val bufferedElements = ListBuffer[(String, Int)]()
    //负责将数据输出到外围系统
    override def invoke(value: (String, Int)): Unit = {
    
    
        bufferedElements += value
        if(bufferedElements.size == threshold){
    
    
            for(ele <- bufferedElements){
    
    
                println(ele)
            }
            bufferedElements.clear()
        }
    }
    //是在savepoint|checkpoint时候将数据持久化
    override def snapshotState(context: FunctionSnapshotContext): Unit = {
    
    
        listState.clear()
        for(ele <- bufferedElements){
    
    
            listState.add(ele)
        }
    }
    //状态恢复|初始化 创建状态
    override def initializeState(context: FunctionInitializationContext): Unit = {
    
    
        val lsd = new ListStateDescriptor[(String, Int)]("buffered-elements",createTypeInformation[(String,Int)])
        //context.getOperatorStateStore.getUnionState(lsd)      //Union方案
        listState=context.getOperatorStateStore.getListState(lsd)   //Even-split方案
        if(context.isRestored){
    
    
            for(element <- listState.get().asScala) {
    
    
                bufferedElements += element
            }
        }
    }
}
var env=StreamExecutionEnvironment.getExecutionEnvironment
	env.socketTextStream("centos",9999)
		.flatMap(_.split("\\s+"))
		.map((_,1))
		.keyBy(0)
		.sum(1)
		.addSink(new BufferingSink(5))
env.execute("operator_state")

:テストするときは、テストを容易にするために、必ずグローバル並列処理を1に設定してください。

添付ファイル:テストで使用された手順:

[root@centos flink-1.8.1]# ./bin/flink list -m centos:8081
------------------ Running/Restarting Jobs -------------------
17.10.2019 09:49:20 : f21795e74312eb06fbf0d48cb8d90489 : testoperatorstate (RUNNING)
--------------------------------------------------------------
[root@centos flink-1.8.1]# ./bin/flink cancel -m centos:8081 -s hdfs:///savepoints f21795e74312eb06fbf0d48cb8d90489
Cancelling job f21795e74312eb06fbf0d48cb8d90489 with savepoint to hdfs:///savepoints.
Cancelled job f21795e74312eb06fbf0d48cb8d90489. Savepoint stored in hdfs://centos:9000/savepoints/savepoint-f21795-38e7beefe07b.

状態を復元するときは、チェックポイントを持参してください。

(2)ListCheckpointed

ListCheckpointedインターフェースは、Even-split状態分散戦略のみをサポートするCheckpointedFunctionインターフェースの変形です

List<T> snapshotState(long checkpointId, long timestamp) throws Exception;
void restoreState(List<T> state) throws Exception;
  • snapshotState():呼び出されるcheckpoint()と、システムはsnapshotState()状態のスナップショットを取得するために呼び出します
  • restoreState():上記CheckpointedFunction宣言さinitializeState()メソッド同等で状態の復元に使用されます。

場合:

import java.lang.{
    
    Long => JLong} //修改类别名
import scala.{
    
    Long => SLong} //修改类别名
class CustomStatefulSourceFunction extends ParallelSourceFunction[SLong] with ListCheckpointed[JLong]{
    
    
  @volatile
  var isRunning:Boolean = true
  var offset = 0L
    
  override def run(ctx: SourceFunction.SourceContext[SLong]): Unit = {
    
    
    val lock = ctx.getCheckpointLock
    while(isRunning){
    
    
       Thread.sleep(1000)
       lock.synchronized({
    
    
         ctx.collect(offset)
         offset += 1
       })
    }
  }

  override def cancel(): Unit = {
    
    
    isRunning=false
  }

  override def snapshotState(checkpointId: Long, timestamp: Long): util.List[JLong] = {
    
    
    Collections.singletonList(offset) //存储的是 当前source的偏移量,如果状态不可拆分,用户可以使Collections.singletonList
  }

  override def restoreState(state: util.List[JLong]): Unit = {
    
    
    for (s <- state.asScala) {
    
    
      offset = s
    }
  }
}
var env=StreamExecutionEnvironment.getExecutionEnvironment
	env.addSource[Long](new CustomStatefulSourceFunction)
		.print("offset:")
env.execute("test_Offset")

さて、Operatorに関するこの記事はこちらです。Keyed状態とOperator状態に加えて、FlinkにはBroadcast状態もあります。ブロガーは以前の記事ですでに共有しています。必要な人はリンクをクリックしてください:https:// blog。 csdn .net / qq_44962429 / article / details / 108100134、ブロガーは2世紀のケースを使用して、キー付きとキーなしのブロードキャスト状態を紹介しました。間違った場所がある場合は、連絡してエラーを指摘してください。ブロガーは喜んで拡大する愛好家と話すために一緒に学び、進歩します。

おすすめ

転載: blog.csdn.net/qq_44962429/article/details/112911553