【Spark】Spark容錯機制

引入

通常來講,分佈式數據集的容錯性有兩種方式:數據檢查點和記錄數據的更新
面向大規模數據分析,數據檢查點操做成本很是高,需要經過數據中心的網絡鏈接在機器之間複製龐大的數據集,而網絡帶寬每每比內存帶寬低得多,同一時候還需要消耗不少其它的存儲資源。git


所以,Spark選擇記錄更新的方式。但是,假設更新粒度太細太多,那麼記錄更新成本也不低。所以。RDD僅僅支持粗粒度轉換,即僅僅記錄單個塊上運行的單個操做,而後將建立RDD的一系列變換序列(每個RDD都包括了他是怎樣由其它RDD變換過來的以及怎樣重建某一塊數據的信息。所以RDD的容錯機制又稱「血統(Lineage)」容錯)記錄下來,以便恢復丟失的分區。
Lineage本質上很是類似於數據庫中的重作日誌(Redo Log),僅僅只是這個重作日誌粒度很是大,是對全局數據作相同的重作進而恢復數據。github

Lineage機制

Lineage簡單介紹

相比其它系統的細顆粒度的內存數據更新級別的備份或者LOG機制,RDD的Lineage記錄的是粗顆粒度的特定數據Transformation操做(如filter、map、join等)行爲。數據庫

當這個RDD的部分分區數據丟失時,它可以經過Lineage獲取足夠的信息來又一次運算和恢復丟失的數據分區。因爲這樣的粗顆粒的數據模型,限制了Spark的運用場合,因此Spark並不適用於所有高性能要求的場景,但同一時候相比細顆粒度的數據模型,也帶來了性能的提高。緩存

兩種依賴關係

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

  • 窄依賴是指父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中的所有數據塊所有又一次計算來恢復。因此在長「血統」鏈特別是有寬依賴的時候,需要在適當的時機設置數據檢查點。ide

也是這兩個特性要求對於不一樣依賴關係要採取不一樣的任務調度機制和容錯恢復機制。post

容錯原理

在容錯機制中,假設一個節點死機了。而且運算窄依賴。則僅僅要把丟失的父RDD分區重算就能夠,不依賴於其它節點。而寬依賴需要父RDD的所有分區都存在,重算就很是昂貴了。

可以這樣理解開銷的經濟與否:在窄依賴中。在子RDD的分區丟失、重算父RDD分區時,父RDD相應分區的所有數據都是子RDD分區的數據,並不存在冗餘計算。

在寬依賴狀況下,丟失一個子RDD分區重算的每個父RDD的每個分區的所有數據並不是都給丟失的子RDD分區用的,會有一部分數據至關於相應的是未丟失的子RDD分區中需要的數據,這樣就會產生冗餘計算開銷,這也是寬依賴開銷更大的緣由。所以假設使用Checkpoint算子來作檢查點,不只要考慮Lineage是否足夠長,也要考慮是否有寬依賴,對寬依賴加Checkpoint是最物有所值的。

Checkpoint機制

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

  1. DAG中的Lineage過長,假設重算,則開銷太大(如在PageRank中)。
  2. 在寬依賴上作Checkpoint得到的收益更大。

因爲RDD是僅僅讀的,因此Spark的RDD計算中一致性不是主要關心的內容,內存相對easy管理,這也是設計者很是有遠見的地方,這樣下降了框架的複雜性,提高了性能和可擴展性,爲之後上層框架的豐富奠基了強有力的基礎。


在RDD計算中。經過檢查點機制進行容錯,傳統作檢查點有兩種方式:經過冗餘數據和日誌記錄更新操做。

在RDD中的doCheckPoint方法至關於經過冗餘數據來緩存數據。而以前介紹的血統就是經過至關粗粒度的記錄更新操做來實現容錯的。

檢查點(本質是經過將RDD寫入Disk作檢查點)是爲了經過lineage作容錯的輔助。lineage過長會形成容錯成本太高。這樣就不如在中間階段作檢查點容錯,假設以後有節點出現故障而丟失分區。從作檢查點的RDD開始重作Lineage,就會下降開銷。

轉載請註明做者Jason Ding及其出處
GitCafe博客主頁(http://jasonding1354.gitcafe.io/)
Github博客主頁(http://jasonding1354.github.io/)
CSDN博客(http://blog.csdn.net/jasonding1354)
簡書主頁(http://www.jianshu.com/users/2bd9b48f6ea8/latest_articles)
Google搜索jasonding1354進入個人博客主頁

相關文章
相關標籤/搜索