重啓策略
- Flink何時纔會重啓?
一個擁有檢查點的應用如果出現問題,他會經過一些列步驟來進行重啓。 - 重啓過程中可能會出現的問題?
有些時候,應用可能會被相同的故障不斷“殺死”
舉例:
當我處理數據的時候程序出現了Bug,導致處理算子出現異常,此時程序就會陷入一個循環中:
啓動任務、恢復狀態、繼續處理。
在繼續處理的時候,由於這個Bug沒有被修復,然後
啓動任務、恢復狀態、繼續處理。
類似於這樣周而復始
… …
Q:問題君來了,這裏面的“啓動任務”我是知道的,後面的“恢復狀態”和“繼續處理”怎麼理解呢?
A:舉個例子你Kafka傳來的數據是如下格式:
a,1
a,2
我的程序會split(“,”)對其進行拆分,然後按照key對value進行相加
此時輸出是:
a,1
a,3
但此時你又傳來一條數據aa傳來的數據中沒有這個逗號,那麼我的程序就會報錯:java.lang.ArrayIndexOutOfBoundsException: 1
既然報錯了,同時因爲你有設置檢查點,那麼此時程序就會重啓,在重啓之後,程序又會讀取aa這條數據,然後又繼續報錯,又進行重啓,周而復始
Q:問題君來了,假如我在代碼中設置讀取kafka的偏移量,只讀取最後一條數據,.setStartFromLatest() //從最新的offset處開始消費。那麼此時我就不會讀取到aa這條數據了,而是讀取最近一條新的正常數據,那麼此時應該就不會報錯了吧。
A:此時還是會報錯,因爲Flink提供了特殊的kafka connector,用於從kafka中讀寫數據。Flink的kafka Consumer 與Flink的檢查點機制集成在一起,以提供有且僅有一次的語義。當你啓用Flink的檢查點後,flink kafka Consumer將在一個topic消費記錄的時候,以一致的方式定期記錄kafka的偏移量並和當前狀態一起寫入檢查點,因此當程序重啓時,Flink還是會從檢查點存儲的Kafka的偏移量處進行消費。因此就算你Kafka設置了偏移量讀取最後一條數據也不行
Q:有且僅有一次怎麼理解?
A:Flink開啓檢查點讀取socket數據的時候就無法保證程序在恢復時,讀取當時socket所傳輸的數據,因爲socket不同於kafka它無法提供某個消費位置,因此無法保證程序恢復後能提供有且一次的一致性保證。
但kafka就可以,因爲kafka能夠提供某個消費位置,可以保證程序在恢復後提供有且一次的一致性保證
配置重啓策略
Flink爲我們提供了三種重啓策略來解決上一節所講到的這種周而復始問題分別是:
-
fixed-delay:
如下代表的是如果失敗了只重啓3次,每次間隔20S
// 配置重啓策略
streamLocal.setRestartStrategy(
RestartStrategies.fixedDelayRestart(
3,
Time.of(20,TimeUnit.SECONDS)
)
) -
no-restart:
代表程序如果失敗了不重啓,直接退出
streamLocal.setRestartStrategy(RestartStrategies.noRestart()) -
failure-rate:
代表的是過去某段時間內,如果失敗的次數沒超過某次,就可以一直重啓
不常用