Spark Streaming 容錯機制

一 Spark中的一致性

1 Spark RDD的基本容錯語義

  1. RDD是不可變的,確定的,可以被重新計算的分布式數(shù)據(jù)集。每個RDD都記錄了已經(jīng)確定的操作先后關(guān)系。
  2. 如果由于任何一個節(jié)點的錯誤導(dǎo)致RDD的任何一個分區(qū)丟失,該分區(qū)都可以從原始的數(shù)據(jù)集中通過操作的先后關(guān)系重新計算出來。
  3. 所有的RDD轉(zhuǎn)換都是明確的,那么在最終轉(zhuǎn)換后的RDD的數(shù)據(jù)總是相關(guān)的,與Spark cluster的錯誤無關(guān)。

可以看到Spark RDD已經(jīng)為我們提供了比較好的容錯能力。Spark進行數(shù)據(jù)的操作在可容錯的文件系統(tǒng)中,如HDFS或者S3。因此從容錯數(shù)據(jù)中生成的所有RDD也是容錯的。為了所有的生成的RDD達到相同的容錯性,RDD的數(shù)據(jù)會在集群中工作節(jié)點上多個executor中創(chuàng)建副本(默認復(fù)制因子是2)。

2 系統(tǒng)異常的場景

1.工作節(jié)點錯誤(Failure of a Worker Node ) 任何執(zhí)行executor的worker node都可能失敗,這些節(jié)點上的內(nèi)存數(shù)據(jù)會丟失。任何運行在一個失敗節(jié)點上的receivers,都會丟失緩存數(shù)據(jù)(buffered data)。
2.Driver節(jié)點錯誤(Failure of the Driver Node) 如果運行Spark Streaming 應(yīng)用的driver node失敗,顯然SparkContext丟失,那么所有executor的內(nèi)存數(shù)據(jù)都會丟失。

3 Spark Streaming中的容錯語義

在理想的情況下,一個系統(tǒng)能夠提供的三種類型的一致性

  1. At most once: 每個record 要么被處理一次或者不會被處理
  2. At least once: 每個record會被處理一次或者多次。 這個比at-most once一致性要強,因為它保證了沒有數(shù)據(jù)會丟失。但是可能會有很多重復(fù)的數(shù)據(jù)。
  3. Exactly once: 每個record都會被處理有且一次。沒有數(shù)據(jù)會丟失,并且也沒有數(shù)據(jù)會被處理多次。這個顯然是三者中一致性最強的。

4 Exactly once的討論

如果要做到Exactly once ,就需要在整個數(shù)據(jù)處理的過程中都做到,包括:

  1. Receiving the data: 數(shù)據(jù)的接收過程
  2. Transforming the data: 數(shù)據(jù)的處理轉(zhuǎn)換過程。Spark Streaming中使用DStream 和 RDD 的轉(zhuǎn)換。由于RDD的機制,Spark的處理保證了exactly once。
  3. Pushing out the data: 數(shù)據(jù)的輸出 最終轉(zhuǎn)換的數(shù)據(jù)輸出到外部的系統(tǒng)中,比如文件系統(tǒng),數(shù)據(jù)庫等。 默認的輸出操作保證了at-least once語義, 但是基于輸出操作和下游的系統(tǒng)(是否支持事務(wù)等)。 但是用戶可以實現(xiàn)自己的事務(wù)機制,以達到exactly-once 語義。
    在數(shù)據(jù)輸出層面,為了達到exactly-once,有兩種方式:
  1. Idempotent updates: 冪等更新 多次寫總是寫相同的數(shù)據(jù)。 例如saveAs***Files 總是將相同的數(shù)據(jù)寫入到文件中。這里比較典型的情況是輸出基于key-value的數(shù)據(jù)庫,即使在at-most-once的情況下,有些數(shù)據(jù)可能會出現(xiàn)多次,但是會多次寫對于最終的輸出正確性也不會有正確性的影響。
  2. Transactional updates: 所以的更新都是基于事務(wù)的,所以所有的更新都是exactly-once.
    一種基于事務(wù)的達到exactly-once方式如下:
  3. 使用foreachRDD中的batch time和RDD的分區(qū)索引(partition index)創(chuàng)建一個標識符。這個標識符唯一標記了streaming 應(yīng)用中的數(shù)據(jù)。
  4. 通過事務(wù)更新這部分數(shù)據(jù)到外部存儲中,如果該標識符沒有提交,那么原子的提交分區(qū)數(shù)據(jù)和標識符。

二 Spark Streaming 與Kafka集成的一致性討論

將Kafka作為Spark Streaming的數(shù)據(jù)輸入端,與Kafka集成的舊API通過基于Receiver的機制來從數(shù)據(jù)源中獲得數(shù)據(jù),有很多相關(guān)的討論如何來達到可靠性以及高性能。 新的API通過Kafka Direct API保證了從Kafka接收的數(shù)據(jù)是exactly once。 舊的Kafka API使用起來需要考慮的問題比較多,推薦使用新的Kafka Direct API。下面也主要圍繞新的API討論。

val directKafkaStream = KafkaUtils.createDirectStream

在該版本中,創(chuàng)建出的directKafkaStream的offset只會在該stream內(nèi)存中存儲,并不會存儲到zookeeper中。根據(jù)上述的討論,為了實現(xiàn)exactly-once,我們有兩種方式:1 在一個事務(wù)中,提交數(shù)據(jù)和offset到存儲中。2 在冪等操作的輸出后,存儲offset。

對于存儲offset 有三個選擇:
1 Checkpoints
啟用kafka的Checkpoints機制。offset會自動的存儲到checkpoint中。啟用Checkpoints的問題也很明顯:如果提交的spark應(yīng)用的代碼發(fā)生了變化之后,不能從checkpoint中進行恢復(fù)。另外,為了達到exactly-once 需要輸出的存儲是冪等的。
2 Kafka中
在Kafka broker version 0.10.0的API中,默認會自動的提交offset到kafka中(實際是寫入到了zookeeper中kafka相關(guān)的路徑中)。但是默認的自動提交的時間我們并不知道,這些數(shù)據(jù)是否寫入的存儲中并不確定。所以應(yīng)當enable.auto.commit置為false。 當數(shù)據(jù)寫入到存儲中時,我們應(yīng)當通過commitAsync API來提交offset到kafka中。由于kafka不是事務(wù)性的,所以為了exactly-once,輸出需要是冪等的。
Kafka broker version 0.8.2.1
在該版本中,并不會提交offset。需要我們自行實現(xiàn)保存offset到zookeeper的功能。 實際上 Kafka broker version 0.10.0所使用的提交offset所用到的類是KafkaCluster,在該版本中存在,只是相關(guān)代碼沒有作為API公開出來。我們可以直接從源碼中提取該類的代碼直接使用。
3 自定義的存儲
能夠存儲offset和結(jié)果數(shù)據(jù)在同一個事務(wù)中。需要我們自己檢測跳過還是采用offset以避免使數(shù)據(jù)重復(fù)或者丟失數(shù)據(jù)。

exactly-once聽起來非常美好,但是在很多應(yīng)用場景下實現(xiàn)成本較高。
在對數(shù)據(jù)可靠性要求不高的場景下,甚至at-least-once都可以作為一個選項,尤其對于數(shù)據(jù)實時性要求更高的場景下。而在工程實踐中,代碼版本的更新迭代是不可避免的,一旦舊版本中出現(xiàn)了bug導(dǎo)致服務(wù)不能正常運行,數(shù)據(jù)將不能恢復(fù),所以并不建議使用checkpoint。

參考
http://spark.apache.org/docs/latest/streaming-programming-guide.html#fault-tolerance-semantics
http://spark.apache.org/docs/latest/streaming-kafka-0-10-integration.html
http://spark.apache.org/docs/latest/streaming-kafka-0-8-integration.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容