[英]Apache flink broadcast state gets flushed
我使用廣播模式連接兩個流並從一個到另一個讀取數據。 代碼看起來像這樣
case class Broadcast extends BroadCastProcessFunction[MyObject,(String,Double), MyObject]{
override def processBroadcastElement(in2: (String, Double),
context: BroadcastProcessFunction[MyObject, (String, Double), MyObject]#Context,
collector:Collector[MyObject]):Unit={
context.getBroadcastState(broadcastStateDescriptor).put(in2._1,in2._2)
}
override def processElement(obj: MyObject,
readOnlyContext:BroadCastProcessFunction[MyObject, (String,Double),
MyObject]#ReadOnlyContext, collector: Collector[MyObject]):Unit={
val theValue = readOnlyContext.getBroadccastState(broadcastStateDesriptor).get(obj.prop)
//If I print the context of the state here sometimes it is empty.
out.collect(MyObject(new, properties, go, here))
}
}
狀態描述符:
val broadcastStateDescriptor: MapStateDescriptor[String, Double) = new MapStateDescriptor[String, Double]("name_for_this", classOf[String], classOf[Double])
我的執行代碼看起來像這樣。
val streamA :DataStream[MyObject] = ...
val streamB :DataStream[(String,Double)] = ...
val broadcastedStream = streamB.broadcast(broadcastStateDescriptor)
streamA.connect(streamB).process(new Broadcast)
問題在於processElement
函數,狀態有時是空的,有時不是。 狀態應該始終包含數據,因為我經常從我知道它有數據的文件流式傳輸。 我不明白為什么它正在沖洗狀態而我無法獲取數據。
我嘗試在將數據放入狀態之前和之后在processBroadcastElement
添加一些打印,結果如下
0 - 1
1 - 2
2 - 3
.. all the way to 48 where it resets back to 0
更新:我注意到的是當我減少流執行上下文的超時值時,結果會更好一些。 當我增加它然后地圖總是空的。
env.setBufferTimeout(1) //better results
env.setBufferTimeout(200) //worse result (default is 100)
每當在Flink中連接兩個流時,您無法控制Flink將事件從兩個流傳遞到您的用戶功能的時間。 因此,例如,如果有一個事件可用於從streamA處理,並且一個事件可用於從streamB處理,則可以接下來處理任何一個事件。 您不能指望broadcastedStream以某種方式優先於其他流。
根據您的要求,您可以采用各種策略來應對兩個流之間的競爭。 例如,您可以使用KeyedBroadcastProcessFunction並使用其applyToKeyedState方法在新廣播事件到達時迭代所有現有的鍵控狀態。
正如大衛所說,這項工作可能正在重新開始。 我禁用了檢查點,因此我可以看到任何可能的異常拋出而不是flink默默地失敗並重新啟動作業。
事實證明,在嘗試解析文件時出錯。 因此,工作一直在重新開始,因此狀態是空的,並且flink不斷地一次又一次地消耗流。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.