Flink-容錯機制 | 一致性檢查點 | 檢查點到恢復狀態過程 | Flink檢查點算法(Chandy-Lamport) | 算法操作解析 | 保存點簡介

一致性檢查點(Checkpoints)

  1. Flink 故障恢復機制的核心,就是應用狀態的一致性檢查點

  2. 有狀態流應用的一致檢查點,其實就是所有任務的狀態,在某個時間點的一份拷貝(一份快照);這個時間點,應該是所有任務都恰好處理完一個相同的輸入數據的時候(如5這個數據雖然進了奇數流但是偶數流也應該做快照,因爲屬於同一個相同數據,只是沒有被他處理)

  3. 在JobManager中也有個Chechpoint的指針,指向了倉庫的狀態快照的一個拓撲圖,爲以後的數據故障恢復做準備

在這裏插入圖片描述

從檢查點恢復狀態

  1. 在執行流應用程序期間,Flink 會定期保存狀態的一致檢查點
  2. 如果發生故障, Flink 將會使用最近的檢查點來一致恢復應用程序的狀態,並重新啓動處理流程(如圖中所示,7這個數據被source讀到了,準備傳給奇數流時,奇數流宕機了,數據傳輸發生中斷

在這裏插入圖片描述

  1. 遇到故障之後,第一步就是重啓應用(重啓後的流都是空的)

在這裏插入圖片描述

  1. 第二步是從 checkpoint 中讀取狀態,將狀態重置(讀取在遠程倉庫(Storage,這裏的倉庫指狀態後端保存數據指定的三種方式之一)保存的狀態),從檢查點重新啓動應用程序後,其內部狀態與檢查點完成時的狀態完全相同

在這裏插入圖片描述

  1. 第三步:開始消費並處理檢查點到發生故障之間的所有數據
  2. 這種檢查點的保存和恢復機制可以爲應用程序狀態提供“精確一次”(exactly-once)的一致性,因爲所有算子都會保存檢查點並恢復其所有狀態,這樣一來所有的輸入流就都會被重置到檢查點完成時的位置

在這裏插入圖片描述

Chandy-Lamport 算法

在上圖所示的數據7,同樣被Source讀取後,在傳向奇數流時,奇數流宕機了,那麼這個數據7在開始已經Source讀取了,但是由於宕機,奇數流又沒有處理到這個數據7,那麼當檢查點恢復後,這個數據7是否還會重新從輸入隊列中讀取,如果不重新讀取則數據將發生丟失,爲了防止這種情況Flink做了改進實現,這種實現叫Chandy-Lamport 算法的分佈式快照,這樣做的好處是將檢查點的保存和數據處理分離開,不暫停整個應用,簡單來說就是Source讀取一個數據,自己就做一份CheckPoint保存,不用管其他數據流是否讀取,其他數據流依然如此,讀取一個數據保存一份數據

Flink 檢查點算法

Flink 檢查點算法

  1. Flink 的檢查點算法用到了一種稱爲分界線(barrier)的特殊數據形式,用來把一條流上數據按照不同的檢查點分開
  2. 分界線之前到來的數據導致的狀態更改,都會被包含在當前分界線所屬的檢查點中;而基於分界線之後的數據導致的所有更改,就會被包含在之後的檢查點中

算法操作解析

  1. 現在是一個有兩個輸入流的應用程序,用並行的兩個 Source 任務來讀取
  2. 兩條自然數數據流,藍色數據流已經輸出完藍3了,黃色數據流輸出完黃4
  3. 在Souce端 Source1 接收到了數據藍3 正在往下游發向一個數據藍2 和 藍3; Source2 接受到了數據黃4,且往下游發送數據黃4
  4. 偶數流已經處理完黃2 所以後面顯示爲2, 奇數流處理完藍1 和 黃1 黃3 所以爲5 並分別往下游發送每次聚合後的結果給Sink

在這裏插入圖片描述

  1. JobManager 會向每個 source 任務發送一條帶有新檢查點 ID 的消息,通過這種方式來啓動檢查點,這個帶有新檢查點ID的東西爲barrier,圖中三角型表示,2只是ID

在這裏插入圖片描述

  1. 在Source端接受到barrier後,將自己此身的3 和 4 的數據,將它們的狀態寫入檢查點,且向JobManager發送checkpoint成功的消息(狀態後端在狀態存入檢查點之後,會返回通知給 source 任務,source 任務就會向 JobManager 確認檢查點完),然後向下遊分別發出一個檢查點 barrier
  2. 可以看出在Source接受barrier時,數據流也在不斷的處理,不會進行中斷,
  3. 此時的偶數流已經處理完藍2變成了4,但是還沒處理到黃4,只是下游發送了一個次數的數據4,而奇數流已經處理完藍3變成了8,並向下遊發送了8
  4. 此時barrier都還未到奇數流和偶數流

在這裏插入圖片描述

  1. 此時藍色流的barrier先一步抵達了偶數流,黃色的barrier還未到,但是因爲數據的不中斷一直處理,此時的先到的藍色的barrier會將此時的偶數流的數據4進行緩存處理,流接着處理接下來的數據等待着黃色的barrier的到來,而黃色barrier之前的數據將會對緩存的數據相加
  2. 這次處理的總結:分界線對齊barrier 向下遊傳遞,sum 任務會等待所有輸入分區的 barrier 到達,對於barrier已經到達的分區,繼續到達的數據會被緩存。而barrier尚未到達的分區,數據會被正常處理

在這裏插入圖片描述

  1. 當藍色的barrier和黃色的barrier(所有分區的)都到達後,進行狀態保存到遠程倉庫,然後對JobManager發送消息,說自己的檢查點保存完畢了
  2. 此時的偶數流和奇數流都爲8
  3. 當收到所有輸入分區的 barrier 時,任務就將其狀態保存到狀態後端的檢查點中,然後將 barrier 繼續向下遊轉發

在這裏插入圖片描述

  1. 向下遊轉發檢查點 barrier 後,任務繼續正常的數據處理

在這裏插入圖片描述

  1. Sink 任務向 JobManager 確認狀態保存到 checkpoint 完畢
  2. 當所有任務都確認已成功將狀態保存到檢查點時,檢查點就真正完成了

在這裏插入圖片描述

保存點(Savepoints)

簡而言之,CheckPoint爲自動保存,SavePoint爲手動保存
在這裏插入圖片描述

CheckPoint配置

 env.enableCheckpointing(1000L) // 開啓 觸發時間間隔爲1000毫秒
    env.getCheckpointConfig.setCheckpointingMode(CheckpointingMode.AT_LEAST_ONCE) // 語義 默認EXACTLY_ONCE
    env.getCheckpointConfig.setCheckpointTimeout(60000L) // 超時時間
    env.getCheckpointConfig.setMaxConcurrentCheckpoints(2) // 最大允許同時出現幾個CheckPoint
    env.getCheckpointConfig.setMinPauseBetweenCheckpoints(500L) // 最小得間隔時間
    env.getCheckpointConfig.setPreferCheckpointForRecovery(true) // 是否傾向於用CheckPoint做故障恢復
    env.getCheckpointConfig.setTolerableCheckpointFailureNumber(3) // 容忍多少次CheckPoint失敗
     // 重啓策略
    // 固定時間重啓
    env.setRestartStrategy(RestartStrategies.fixedDelayRestart(3, 10000L))
    // 失敗率重啓
    env.setRestartStrategy(RestartStrategies.failureRateRestart(5, Time.of(5, TimeUnit.MINUTES), Time.of(10, TimeUnit.SECONDS)))

在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章