# 容錯語義
這一節,我們將討論在節點錯誤事件時Spark Streaming的行為。為了理解這些,讓我們先記住一些Spark RDD的基本容錯語義。
- 一個RDD是不可變的、確定可重復計算的、分布式數據集。每個RDD記住一個確定性操作的譜系(lineage),這個譜系用在容錯的輸入數據集上來創建該RDD。
- 如果任何一個RDD的分區因為節點故障而丟失,這個分區可以通過操作譜系從源容錯的數據集中重新計算得到。
- 假定所有的RDD transformations是確定的,那么最終轉換的數據是一樣的,不論Spark機器中發生何種錯誤。
Spark運行在像HDFS或S3等容錯系統的數據上。因此,任何從容錯數據而來的RDD都是容錯的。然而,這不是在Spark Streaming的情況下,因為Spark Streaming的數據大部分情況下是從
網絡中得到的。為了獲得生成的RDD相同的容錯屬性,接收的數據需要重復保存在worker node的多個Spark executor上(默認的復制因子是2),這導致了當出現錯誤事件時,有兩類數據需要被恢復
- Data received and replicated :在單個worker節點的故障中,這個數據會幸存下來,因為有另外一個節點保存有這個數據的副本。
- Data received but buffered for replication:因為沒有重復保存,所以為了恢復數據,唯一的辦法是從源中重新讀取數據。
有兩種錯誤我們需要關心
- worker節點故障:任何運行executor的worker節點都有可能出故障,那樣在這個節點中的所有內存數據都會丟失。如果有任何receiver運行在錯誤節點,它們的緩存數據將會丟失
- Driver節點故障:如果運行Spark Streaming應用程序的Driver節點出現故障,很明顯SparkContext將會丟失,所有執行在其上的executors也會丟失。
## 作為輸入源的文件語義(Semantics with files as input source)
如果所有的輸入數據都存在于一個容錯的文件系統如HDFS,Spark Streaming總可以從任何錯誤中恢復并且執行所有數據。這給出了一個恰好一次(exactly-once)語義,即無論發生什么故障,
所有的數據都將會恰好處理一次。
## 基于receiver的輸入源語義
對于基于receiver的輸入源,容錯的語義既依賴于故障的情形也依賴于receiver的類型。正如之前討論的,有兩種類型的receiver
- Reliable Receiver:這些receivers只有在確保數據復制之后才會告知可靠源。如果這樣一個receiver失敗了,緩沖(非復制)數據不會被源所承認。如果receiver重啟,源會重發數
據,因此不會丟失數據。
- Unreliable Receiver:當worker或者driver節點故障,這種receiver會丟失數據
選擇哪種類型的receiver依賴于這些語義。如果一個worker節點出現故障,Reliable Receiver不會丟失數據,Unreliable Receiver會丟失接收了但是沒有復制的數據。如果driver節點
出現故障,除了以上情況下的數據丟失,所有過去接收并復制到內存中的數據都會丟失,這會影響有狀態transformation的結果。
為了避免丟失過去接收的數據,Spark 1.2引入了一個實驗性的特征`write ahead logs`,它保存接收的數據到容錯存儲系統中。有了`write ahead logs`和Reliable Receiver,我們可以
做到零數據丟失以及exactly-once語義。
下面的表格總結了錯誤語義:
Deployment Scenario | Worker Failure | Driver Failure
--- | --- | ---
Spark 1.1 或者更早, 沒有write ahead log的Spark 1.2 | 在Unreliable Receiver情況下緩沖數據丟失;在Reliable Receiver和文件的情況下,零數據丟失 | 在Unreliable Receiver情況下緩沖數據丟失;在所有receiver情況下,過去的數據丟失;在文件的情況下,零數據丟失
帶有write ahead log的Spark 1.2 | 在Reliable Receiver和文件的情況下,零數據丟失 | 在Reliable Receiver和文件的情況下,零數據丟失
## 輸出操作的語義
根據其確定操作的譜系,所有數據都被建模成了RDD,所有的重新計算都會產生同樣的結果。所有的DStream transformation都有exactly-once語義。那就是說,即使某個worker節點出現
故障,最終的轉換結果都是一樣。然而,輸出操作(如`foreachRDD`)具有`at-least once`語義,那就是說,在有worker事件故障的情況下,變換后的數據可能被寫入到一個外部實體不止一次。
利用`saveAs***Files`將數據保存到HDFS中的情況下,以上寫多次是能夠被接受的(因為文件會被相同的數據覆蓋)。
- Introduction
- 快速上手
- Spark Shell
- 獨立應用程序
- 開始翻滾吧!
- RDD編程基礎
- 基礎介紹
- 外部數據集
- RDD 操作
- 轉換Transformations
- map與flatMap解析
- 動作Actions
- RDD持久化
- RDD容錯機制
- 傳遞函數到 Spark
- 使用鍵值對
- RDD依賴關系與DAG
- 共享變量
- Spark Streaming
- 一個快速的例子
- 基本概念
- 關聯
- 初始化StreamingContext
- 離散流
- 輸入DStreams
- DStream中的轉換
- DStream的輸出操作
- 緩存或持久化
- Checkpointing
- 部署應用程序
- 監控應用程序
- 性能調優
- 減少批數據的執行時間
- 設置正確的批容量
- 內存調優
- 容錯語義
- Spark SQL
- 概述
- SparkSQLvsHiveSQL
- 數據源
- RDDs
- parquet文件
- JSON數據集
- Hive表
- 數據源例子
- join操作
- 聚合操作
- 性能調優
- 其他
- Spark SQL數據類型
- 其它SQL接口
- 編寫語言集成(Language-Integrated)的相關查詢
- GraphX編程指南
- 開始
- 屬性圖
- 圖操作符
- Pregel API
- 圖構造者
- 部署
- 頂點和邊RDDs
- 圖算法
- 例子
- 更多文檔
- 提交應用程序
- 獨立運行Spark
- 在yarn上運行Spark
- Spark配置
- RDD 持久化