Spark容錯機制

轉載地址:https://www.jianshu.com/p/99ebcc7c92d3

引入

一般來說,分佈式數據集的容錯性有兩種方式:數據檢查點和記錄數據的更新
面向大規模數據分析,數據檢查點操作成本很高,需要通過數據中心的網絡連接在機器之間複製龐大的數據集,而網絡帶寬往往比內存帶寬低得多,同時還需要消耗更多的存儲資源。
因此,Spark選擇記錄更新的方式。但是,如果更新粒度太細太多,那麼記錄更新成本也不低。因此,RDD只支持粗粒度轉換,即只記錄單個塊上執行的單個操作,然後將創建RDD的一系列變換序列(每個RDD都包含了他是如何由其他RDD變換過來的以及如何重建某一塊數據的信息。因此RDD的容錯機制又稱“血統(Lineage)”容錯)記錄下來,以便恢復丟失的分區。
Lineage本質上很類似於數據庫中的重做日誌(Redo Log),只不過這個重做日誌粒度很大,是對全局數據做同樣的重做進而恢復數據。

Lineage機制

Lineage簡介

相比其他系統的細顆粒度的內存數據更新級別的備份或者LOG機制,RDD的Lineage記錄的是粗顆粒度的特定數據Transformation操作(如filter、map、join等)行爲。當這個RDD的部分分區數據丟失時,它可以通過Lineage獲取足夠的信息來重新運算和恢復丟失的數據分區。因爲這種粗顆粒的數據模型,限制了Spark的運用場合,所以Spark並不適用於所有高性能要求的場景,但同時相比細顆粒度的數據模型,也帶來了性能的提升。

兩種依賴關係

RDD在Lineage依賴方面分爲兩種:窄依賴(Narrow Dependencies)與寬依賴(Wide Dependencies,源碼中稱爲Shuffle
Dependencies),用來解決數據容錯的高效性。

  • 窄依賴是指父RDD的每一個分區最多被一個子RDD的分區所用,表現爲一個父RDD的分區對應於一個子RDD的分區
    或多個父RDD的分區對應於一個子RDD的分區,也就是說一個父RDD的一個分區不可能對應一個子RDD的多個分區。
    1個父RDD分區對應1個子RDD分區,這其中又分兩種情況:1個子RDD分區對應1個父RDD分區(如map、filter等算子),1個子RDD分區對應N個父RDD分區(如co-paritioned(協同劃分)過的Join)。
  • 寬依賴是指子RDD的分區依賴於父RDD的多個分區或所有分區,即存在一個父RDD的一個分區對應一個子RDD的多個分區。
    1個父RDD分區對應多個子RDD分區,這其中又分兩種情況:1個父RDD對應所有子RDD分區(未經協同劃分的Join)或者1個父RDD對應非全部的多個RDD分區(如groupByKey)。


本質理解:根據父RDD分區是對應1個還是多個子RDD分區來區分窄依賴(父分區對應一個子分區)和寬依賴(父分區對應多個子分
區)。如果對應多個,則當容錯重算分區時,因爲父分區數據只有一部分是需要重算子分區的,其餘數據重算就造成了冗餘計算。

對於寬依賴,Stage計算的輸入和輸出在不同的節點上,對於輸入節點完好,而輸出節點死機的情況,通過重新計算恢復數據這種情況下,這種方法容錯是有效的,否則無效,因爲無法重試,需要向上追溯其祖先看是否可以重試(這就是lineage,血統的意思),窄依賴對於數據的重算開銷要遠小於寬依賴的數據重算開銷。

窄依賴和寬依賴的概念主要用在兩個地方:一個是容錯中相當於Redo日誌的功能;另一個是在調度中構建DAG作爲不同Stage的劃分點。

依賴關係的特性

第一,窄依賴可以在某個計算節點上直接通過計算父RDD的某塊數據計算得到子RDD對應的某塊數據;寬依賴則要等到父RDD所有數據都計算完成之後,並且父RDD的計算結果進行hash並傳到對應節點上之後才能計算子RDD。
第二,數據丟失時,對於窄依賴只需要重新計算丟失的那一塊數據來恢復;對於寬依賴則要將祖先RDD中的所有數據塊全部重新計算來恢復。所以在長“血統”鏈特別是有寬依賴的時候,需要在適當的時機設置數據檢查點。也是這兩個特性要求對於不同依賴關係要採取不同的任務調度機制和容錯恢復機制。

容錯原理

在容錯機制中,如果一個節點死機了,而且運算窄依賴,則只要把丟失的父RDD分區重算即可,不依賴於其他節點。而寬依賴需要父RDD的所有分區都存在,重算就很昂貴了。可以這樣理解開銷的經濟與否:在窄依賴中,在子RDD的分區丟失、重算父RDD分區時,父RDD相應分區的所有數據都是子RDD分區的數據,並不存在冗餘計算。在寬依賴情況下,丟失一個子RDD分區重算的每個父RDD的每個分區的所有數據並不是都給丟失的子RDD分區用的,會有一部分數據相當於對應的是未丟失的子RDD分區中需要的數據,這樣就會產生冗餘計算開銷,這也是寬依賴開銷更大的原因。因此如果使用Checkpoint算子來做檢查點,不僅要考慮Lineage是否足夠長,也要考慮是否有寬依賴,對寬依賴加Checkpoint是最物有所值的。

Checkpoint機制

通過上述分析可以看出在以下兩種情況下,RDD需要加檢查點。

  1. DAG中的Lineage過長,如果重算,則開銷太大(如在PageRank中)。
  1. 在寬依賴上做Checkpoint獲得的收益更大。

由於RDD是隻讀的,所以Spark的RDD計算中一致性不是主要關心的內容,內存相對容易管理,這也是設計者很有遠見的地方,這樣減少了框架的複雜性,提升了性能和可擴展性,爲以後上層框架的豐富奠定了強有力的基礎。
在RDD計算中,通過檢查點機制進行容錯,傳統做檢查點有兩種方式:通過冗餘數據和日誌記錄更新操作。在RDD中的doCheckPoint方法相當於通過冗餘數據來緩存數據,而之前介紹的血統就是通過相當粗粒度的記錄更新操作來實現容錯的。

檢查點(本質是通過將RDD寫入Disk做檢查點)是爲了通過lineage做容錯的輔助,lineage過長會造成容錯成本過高,這樣就不如在中間階段做檢查點容錯,如果之後有節點出現問題而丟失分區,從做檢查點的RDD開始重做Lineage,就會減少開銷。


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