《Flink 技術內幕之Data Streaming 容錯》(官網翻譯)

目錄

一、介紹

二、Checkpoint

三、Barriers

四、State

​ 五、精確一次和至少一次

六、異步狀態快照

七、Recovery

八、Operator 快照實現


一、介紹

Apache Flink提供了一種容錯機制,可以一致地恢復數據流應用程序的狀態。該機制確保即使出現故障,程序的狀態最終也將準確地反映數據流中的每條記錄(exactly once)。請注意,有一個開關將保證降級到至少一次(如下所述)。

容錯機制不斷地繪製分佈式流數據流的快照。對於狀態較小的流應用程序,這些快照非常輕量級,可以頻繁地繪製,而不會對性能造成太大影響。流應用程序的狀態存儲在一個可配置的位置(例如主節點或HDFS)。

如果程序失敗(由於機器、網絡或軟件故障),Flink將停止分佈式流數據流。然後系統重新啓動operators,並將它們重置爲最新的成功檢查點。輸入流被重置爲狀態快照的點。任何作爲重新啓動的並行數據流的記錄都保證不屬於以前檢查點狀態的一部分。

注意:默認情況下,檢查點是禁用的。有關如何啓用和配置檢查點的詳細信息,請參閱檢查點。

注意:要使此機制實現其全部保證,數據源(如消息隊列或代理)需要能夠將流回滾到定義的最近點。Apache Kafka有這個功能,Flink到Kafka的connector 利用了這個功能。有關Flink連接器提供的保證的更多信息,請參閱數據源和接收器的容錯保證

注意:因爲Flink的檢查點是通過分佈式快照實現的,所以我們可以互換使用snapshot和檢查點這兩個詞。

二、Checkpoint

Flink容錯機制的核心部分是繪製分佈式數據流和操作符狀態的一致快照。這些快照充當一致的檢查點,在出現故障時,系統可以退回到這些檢查點。Flink繪製這些快照的機制在“Lightweight Asynchronous Snapshots for Distributed Dataflows”中進行了描述。它受到分佈式快照的標準Chandy-Lamport算法的啓發,並特別針對Flink的執行模型進行了調整。】

三、Barriers

Flink分佈式快照的一個核心元素是stream barriers。這些barriers被注入到數據流中,並和記錄一起成爲數據流的一部分。barriers永遠追不上記錄,流嚴格按照規定進行。一個barrier將數據流中的記錄分隔爲進入當前快照的記錄集和進入下一個快照的記錄集。每個barrier都攜帶快照的ID,這個快照的記錄都已被推到barrier(ID)的前面。barrier不會中斷流,因此非常輕。來自不同快照的多個barrier可以同時出現在流中,這意味着各種快照可能同時發生。

Stream barriers被注入stream source的並行數據流。快照n的barrier被注入的位置(我們稱之爲Sn)是stream source中快照覆蓋數據的位置。例如,在Apache Kafka中,這個位置將是分區中最後一條記錄的offset。這個位置Sn報告給檢查點協調器(Flink的作業管理器)。

這些barriers隨後流向下游。當一箇中間operator從其所有輸入流接收到快照n的barrier時,它將快照n的barrier發送到其所有輸出流。一旦一個sink operator(streaming  DAG的末尾)從其所有輸入流接收到barrier n,它就向檢查點協調器確認快照n。在所有sink operator都確認快照之後,就認爲快照已經完成。

快照n完成後,作業將不再向source 請求來自Sn之前的記錄,因爲此時這些記錄(及其後代記錄)已經通過了整個數據流拓撲。

接收多個輸入流的operators 需要在快照barriers上對齊輸入流。上圖說明了這一點: 

  • 一旦operator從輸入流接收到快照barrier n,它就不能再處理來自該流的任何其他記錄,直到它也從其他輸入接收到barrier n。否則,它將混淆屬於snapshot n的記錄和屬於snapshot n+1的記錄。
  • 報告barrier n的流被暫時擱置。從這些流接收的記錄不會被處理,而是被放入輸入緩衝區。
  • 一旦最後一個流接收到barrier n,操作符將發出所有掛起的輸出記錄,然後自己發出snapshot n barrier。
  • 之後,它將繼續處理來自所有輸入流的記錄,在處理來自流的記錄之前處理來自輸入緩衝區的記錄。

四、State

當操作符包含任何形式的狀態時,此狀態也必須是快照的一部分。操作符狀態有不同的形式:

  • 用戶定義狀態:這是由轉換函數(如map()或filter())直接創建和修改的狀態。有關詳細信息,請參見流應用程序中的狀態。
  • 系統狀態:這個狀態是指數據緩衝區(operator計算的一部分)。這種狀態的一個典型例子是窗口緩衝區,系統在其中收集(和聚合)窗口記錄,直到計算和清除窗口爲止。

operator 在從其輸入流接收到所有快照barriers時,在將barriers發送到其輸出流之前,對其狀態進行快照。此時,對barrier之前的記錄的所有狀態更新都已完成,並且在barrier之後不會對依賴於barrier之後的記錄進行更新。因爲快照的狀態可能很大,所以它存儲在一個可配置的state backend。默認情況下,是JobManager的內存,但是對於生產使用,應該配置分佈式可靠存儲(例如HDFS)。在狀態存儲之後,operator確認檢查點,將快照屏障發送到輸出流中,然後繼續。

生成的快照現在包含:

五、精確一次和至少一次

 

  • 對於每個並行流數據源,快照啓動時流中的偏移量/位置
  • 對於每個操作符,指向作爲快照的一部分存儲的狀態的指針

對齊步驟可能會給流程序增加延遲。通常,這種額外的延遲約爲幾毫秒,但是我們已經看到一些異常的延遲明顯增加的情況。對於所有記錄都需要持續超低延遲(幾毫秒)的應用程序,Flink有一個開關,可以在檢查點期間跳過流對齊。當operator 從每個輸入中看到檢查點屏障時,檢查點快照仍然被繪製出來。

當跳過對齊時,operator 將持續處理所有輸入,即使在檢查點n的某些檢查點屏障到達之後也是如此。這樣,在獲取檢查點n的狀態快照之前,操作符還處理屬於檢查點n+1的元素。在恢復時,這些記錄將以重複的形式出現,因爲它們都包含在檢查點n的狀態快照中,並且將在檢查點n之後作爲數據的一部分重新播放。

注意:對齊只發生在具有多個前身(連接)的operator和具有多個發送者的operator(在流重新分區/洗牌之後)。因此,只有令人尷尬的並行流操作(map()、flatMap()、filter()、…)的數據流實際上只提供一次保證,即使在至少一次模式下也是如此。

六、異步狀態快照

注意,上面描述的機制意味着operator在state backend 存儲狀態快照時停止處理輸入記錄。每次捕獲快照時,此同步狀態快照都會引入延遲。

可以讓operator 在存儲狀態快照時繼續處理,從而有效地讓狀態快照在後臺異步發生。要做到這一點,operator必須能夠生成一個狀態對象,該對象應該以一種對operator狀態的進一步修改不會影響該狀態對象的方式存儲。例如,在RocksDB中使用的即寫即拷數據結構具有這種行爲。

在接收到其輸入上的檢查點屏障之後,operator啓動對其狀態的異步快照複製。它立即向輸出發出屏障,並繼續進行常規的流處理。一旦後臺複製過程完成,它向檢查點協調器(JobManager)確認檢查點。檢查點現在只有在所有接收到屏障和所有有狀態operator確認它們的完整備份(可能是在屏障到達接收點之後)之後才完成。

有關狀態快照的詳細信息,請參見state backend

七、Recovery

恢復在這種機制下非常簡單:當失敗時,Flink選擇最新的完整檢查點k。然後系統重新部署整個分佈式數據流,並給出存儲在檢查點k中的每個opeartor的狀態。source設置爲從Sk的處讀取流。例如在Apache Kafka,這意味着告訴消費者開始從 offset Sk處獲取。

如果以增量方式快照狀態,操作符將從最新完整快照的狀態開始,然後對該狀態應用一系列增量快照更新。

有關更多信息,請參見重啓策略

八、Operator 快照實現

operator快照拍攝可分爲兩部分:同步部分和異步部分。

operator和state backend 以Java FutureTask 形式提供快照。該任務包含同步完成部分和異步掛起部分的狀態。然後,異步部分由該檢查點的後臺線程執行。

完全同步檢查點operator返回一個已經完成的FutureTask。如果需要執行異步操作,則在該FutureTask的run()方法中執行。

這些任務是可取消的,因此可以釋放流和其他資源消耗句柄。

原文地址:https://ci.apache.org/projects/flink/flink-docs-release-1.7/internals/stream_checkpointing.html

注:轉載請註明出處

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