Spark 定製版:012~Spark Streaming源碼解讀之Executor容錯安全性

本講內容:

a. Executor的WAL機制詳解
b. 消息重放Kafka

注:本講內容基於Spark 1.6.1版本(在2016年5月來說是Spark最新版本)講解。

上節回顧

上一講中,我們主要解密了ReceiverTracker具體的架構及其功能、源碼實現;

ReceiverTracker的架構設計

a. ReceiverTracker以Driver中具體的算法在具體的Executor之上啓動Receiver,而且啓動Receiver的方式是把每個Receiver封裝成一個Task, 此時一個Job中就一個Task,而Task中就一條數據,也就是Receiver數據,實質上說,ReceiverTracker啓動Receiver之時就會封裝在一個個Job,有多個Job就有多個Receiver,即有多個Receiver啓動就有多個Job封裝

b. ReceiverTracker在啓動Receiver的時候,有一個Receiversupervisor其裏面有一個ReceiversupervisorImpl實現類, Receiversupervisor實際上啓動之時就啓動了Receiver,Receiver不斷的接收數據,通過BlockGenerator把自已“接收的數據”變成一個個的Block。然後在時間定時器的作用下會不斷的把數據存儲(此時存儲有2種方式,第一種是通過BlockManager方式存儲,另一種先寫日誌Write,通過WAL方式),數據存儲之後ReceiverSupervisorImpl會把存儲後的數據的元數據Metadate彙報給ReceiverTracker,其實是彙報給ReceiverTracker中的RPC實體ReceiverTrackerEndpoint

c. ReceiverTracker用來管理Receiver中的數據執行,數據執行層面包括Receiver的啓動、回收、執行過程中接收數據的管理,當然也包括“Receiver”的容錯

d. Receiver接收到數據之後合併存儲數據後,ReceiverSupervisorImpl會把數據彙報給ReceiverTracker, ReceiverTracker接收到元數據,其內部彙報的是RPC通信體,接收到數據之後,內部有ReceivedBlockTracker會管理數據的分配,JobGenerator會將每個Batch,每次工作的時候會根據元數據信息從ReceiverTracker中獲取相應的元數據信息生成RDD。

e. ReceiverBlockTracker中 allocateBlocksToBatch專門管理Block元數據信息,作爲一個內部的管理對象。

還了解了什麼是門面設計模式

從設計模式來講:ReceiverTrackerEndpoint和ReceivedBlockTracker是門面設計模式,。

ReceiverTracker和ReceivedBlockTracker的關係是:內部實際幹事情的是ReceivedBlockTracker,外部通信體或者代表者就是ReceiverTracker

開講

本講我們從安全角度來講解Spark Streaming,由於Spark Streaming會不斷的接收數據、不斷的產生job、不斷的提交job。所以數據的安全性至關重要。

首先我們來談談,對於數據安全性的考慮:

a. Spark Streaming是基於Spark Core之上的,如果能夠確保數據安全可好的話,在Spark Streaming生成Job的時候裏面是基於RDD,即使運行的時候出現問題,那麼Spark Streaming也可以藉助Spark Core的容錯機制自動容錯

b. 對於executor的安全容錯主要是數據的安全容錯。Executor計算時候的安全容錯是藉助Spark core的RDD的,所以天然是安全的

那麼Executor容錯方式是什麼呢?

a. 最簡單的容錯是副本方式,基於底層BlockManager副本容錯,也是默認的容錯方式

b. 接收到數據之後不做副本,支持數據重放,所謂重放就是支持反覆讀取數據

這裏寫圖片描述

ReceiverSupervisorImpl在存儲數據的時候會有兩種方式,一種是WAL的方式,究竟是不是WAL得方式是通過配置修改的。默認是false。如果用WAL的方式必須有checkpoint的目錄,因爲WAL的數據是放在checkpoint的目錄之下的

這裏寫圖片描述

這裏寫圖片描述

BlockManager備份

Blockmanager存儲數據的時候有很多storagelevel,Receiver接收數據後,存儲的時候指定storagelevel爲MEMORY_AND_DISK_SER_2的方式。Blockmanager早存儲的時候會先考慮memory,只有memory不夠的時候纔會考慮disk,一般memory都是夠的。所以至少兩個executor上都會有數據,假設一個executor掛掉,就會馬上切換到另一個executor

這裏寫圖片描述

Storagelevel是在構建InputDStream的時候傳入的,默認就是MEMORY_AND_DISK_SER_2

這裏寫圖片描述

我們來看看Receiver,發現都有StorageLevel變量

這裏寫圖片描述

現在來看ReceiverSupervisorImpl

這裏寫圖片描述

所以ReceiverSupervisorImpl在以副本方式存儲數據的時候;根據指定的storagelevel把接收的blocks交給blockmanager。也就是通過blockmanager來存儲

這裏寫圖片描述

Blockmanager存儲的時候會分爲多種不同的數據類型,ArrayBufferBlock,IteratorBlock,ByteBufferBlock

有上面的BlockManagerBasedBlockHandler源碼具體實現是通過putIterator

這裏寫圖片描述

doPut源碼如下

這裏寫圖片描述

這裏寫圖片描述

replicate源碼如下:

這裏寫圖片描述

把數據備份到另一個節點

WAL方式

WAL的方式原理:在具體的目錄下會做一份日誌,假設後續處理的過程中出了問題,可以基於日誌恢復,日誌是寫在checkpoint下。在生產環境下checkpoint是在HDFS上,這樣日誌就會有三份副本

這裏寫圖片描述

進入到ReceivedBlockHandler源碼

這裏寫圖片描述

進入到WriteAheadLogBasedBlockHandler源碼

這裏寫圖片描述

使用WAL,就沒必要將replication變成2份。WAL是寫到checkpoint目錄中,而checkpoint是保持在HDFS中,HDFS默認是3份副本

存儲數據的時候是同時往WAL和BlockManager中放數據

這裏寫圖片描述

然後將數據存儲到BlockManager中

這裏寫圖片描述

使用write方法寫入到log中

這裏寫圖片描述

WAL寫數據的時候是順序寫,數據不可修改,所以讀的時候只需要按照指針(也就是要讀的record在那,長度是多少)讀即可。所以WAL的速度非常快

這裏寫圖片描述

FileBasedWriteAheadLog管理WAL文件

這裏寫圖片描述

直接將數據寫入到HDFS的checkpoint

這裏寫圖片描述

不同時間不同條件下,會寫入到不同的文件中,會有很多小文件

這裏寫圖片描述

Read部分

這裏寫圖片描述

不管是WAL還是直接交給blockmanager都是採用副本的方式。還有一種是數據源支持數據存放,典型的就是kafka。Kafka已經成爲了數據存儲系統,它天然具有容錯和數據副本

Kafka有receiver和direct的方式。Receiver的方式其實是交給zookeper來管理matadata的(偏移量offset),如果數據處理失敗後,kafka會基於offset重新讀取數據。爲什麼可以重新讀取?如果程序崩潰或者數據沒處理完是不會給zookeper發ack。Zookeper就認爲這個數據沒有被消費。實際生產環境下越來越多的使用directAPI的方式,直接去操作kafka並且是自己管理offset。這就可以保證有且只有一次的容錯處理。DirectKafkaInputDstream,它會去看最新的offset,並把這個內容放入batch中

獲取最新的offset,通過最新的offset減去上一個offset就可以確定讀哪些數據,也就是一個batch中的數據

這裏寫圖片描述

a. 容錯的弊端就是消耗性能,佔用時間。也不是所有情況都不能容忍數據丟失。有些情況下可以不進行容錯來提高性能

b. 假如一次處理1000個block,但是有1個block出錯,就需要把1000個block進行重新讀取或者恢復,這也有性能問題

發佈了42 篇原創文章 · 獲贊 11 · 訪問量 17萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章