第4課:Spark Streaming的Exactly Once的事務處理

本期內容:

Exactly once

輸出不重複


Exactly once

1,事務一定會被處理,且只被處理一次;

2,輸出能夠輸出且只會被輸出。


  • Receiver:數據通過BlockManager寫入內存+磁盤或者通過WAL來保證數據的安全性。
  • WAL機制:寫數據時先通過WAL寫入文件系統然後存儲的Executor(存儲在內存和磁盤中,由StorageLevel設定),假設前面沒有寫成功後面一定不會存儲在Executor,如不存在Executor中的話,彙報Driver數據一定不被處理。WAL能對要寫入的數據,能保證其安全,失敗的可能性不大。
  • 注意點:Receiver會把數據積累到一定程度才能寫入內存磁盤或WAL,如果還沒積累到一定程度,Executor或Receiver崩潰了怎麼辦?答案是數據還是可能會丟失幾條。因爲尚未做備份,根本沒有準備好數據塊。
  • SparkStreaming說白了就兩點:獲取數據和產生作業。作業是通過SparkContext來執行的。
  • 關於恢復:Driver級別的恢復:直接在Driver進行Checkpoint文件系統把數據讀入,內部則重啓SparkContext。InputDStream是Driver端產生的(因爲是框架調度層面的),這是在邏輯級別而言的。恢復過數據後,重新構建StreamingContext其實也就是構建SparkContext,恢復出的源數據再次產生RDD。恢復時根據上次的Job執行,所以恢復對應的Job,再次提交至Spark集羣,再次執行。另一方面,Receiver重新恢復,在以前的數據基礎上接收數據,曾經接收的數據根據WAL之類的機制從磁盤中恢復回來。通過這種方式 ,SparkStreaming是個相對可靠的系統,Driver發生故障後重新啓動可以在原有基礎上繼續執行,這樣我們就可以繼續原有任務而不丟失數據。
  • Receiver只接收幾條,沒有及時WAL其實還是會丟失數據的,這是從整體SparkStreaming考慮而言的;而和Kafka結合的話不會有上面這種問題。
  • 我們要做SparkStreaming的話,必須從生產作業流水線考慮輸入和輸出。外部數據源輸入Kafka,然後通過Kafka再交給SparkStreaming,SparkStreaming通過處理後將數據交給離線存儲系統或繼續交給Kafka或交給實時消費系統

Exactly Once的事務處理:

1,數據零丟失:必須有可靠的數據來源和可靠的Receiver,且整個應用程序的metadata必須進行checkpoint,且通過WAL來保證數據安全;

2,Spark Streaming 1.3的時候爲了避免WAL的性能損失和實現Exactly Once而提供了Kafka Direct API,Kafka作爲文件存儲系統!!!

      此時兼具有流的優勢和文件系統的優勢,至此,Spark Streaming+Kafka就構建了完美的流處理世界!!!

      所有的Executors通過Kafka API直接消費數據,直接管理Offset,所以也不會重複消費數據;事務實現啦!!!

數據丟失及其具體的解決方式:

在Receiver收到數據且通過Driver的調度Executor開始計算數據的時候如果Driver突然崩潰,則此時Executor會被Kill掉,那麼Executor中的數據就會丟失,此時就必須通過例如WAL的方式讓所有的數據都通過例如HDFS的方式首先進行安全性容錯處理,此時如果Executor中的數據丟失的話就可以通過WAL恢復回來;

數據重複讀取的情況:

在Receiver收到數據且保存到了HDFS等持久化引擎但是沒有來得及進行updateOffsets,此時Receiver崩潰後重新啓動就會通過管理Kafka的ZooKeeper中元數據再次重複讀取數據,但是此時SparkStreaming認爲是成功的,但是Kafka認爲是失敗的(因爲沒有更新offset到ZooKeeper中),此時就會導致數據重新消費的情況。

性能損失:
1,通過WAL方式會極大的損傷Spark Streaming中Receivers接受數據的性能;
2,如果通過Kafka的作爲數據來源的話,Kafka中有數據,然後Receiver接受的時候又會有數據副本,這個時候其實是存儲資源的浪費;

關於Spark Streaming數據輸出多次重寫及其解決方案:

1,爲什麼會有這個問題,因爲SparkStreaming在計算的時候基於SparkCoreSparkCore天生會做以下事情導致SparkStreaming的結果(部分)重複輸出:

  Task重試;

  慢任務推測;

  Stage重複;

  Job重試;

2,具體解決方案:

  設置spark.task.maxFailures次數爲1;

  設置spark.speculation爲關閉狀態(因爲慢任務推測其實非常消耗性能,所以關閉後可以顯著提高Spark Streaming處理性能)

  Spark Streaming on Kafka的話,Job失敗後可以設置auto.offset.reset爲“largest”的方式。


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