關於SparkStreaming的checkpoint問題

在流式運行程序運行時,必須全天24小時的運行,因此我們必須應對與應用程序邏輯無關的故障(例如系統故障,JVM崩潰等)

爲此,Spark Streaming需要將足夠的信息檢查點指向容錯存儲系統,以便可以從故障中恢復。

檢查點有兩種類型的數據。

1、元數據檢查點---將定義流計算的信息保存到HDFS等容錯存儲中。

這用於從運行流應用程序的驅動程序的節點的故障中恢復。

元數據包括:
    配置 ---用於創建流應用程序的配置。
    DStream操作 ---定義流應用程序的DStream操作集。
    不完整的批次 ---作業排隊但尚未完成的批次。


2、數據檢查點 --- 將生成的RDD保存到可靠的存儲中。

在某些狀態轉換中,這是必須的,這些轉換將跨多個批次的數據進行合併。在此類轉換中,生成的RDD依賴於先前批次的RDD,這導致依賴項鍊的長度隨時間不斷增加。爲了避免恢復的時候這種無限制的增加,有狀態轉換的中間RDD定期落地到(通過檢查點)到可靠的存儲(例如HDFS),以切斷依存關係鏈。


總而言之,從驅動程序故障中恢復時,需要元數據檢查點,而如果使用有狀態轉換的數據或者RDD,即使是基本功能,也需要數據或RDD檢查點。

何時使用檢查點

必須爲具有以下任何要求的應用程序啓用檢查點:

1、有狀態轉換的用法

      如果在應用程序中使用updateStateByKeyreduceByKeyAndWindow等,則必須提供檢查點目錄以允許定期進行RDD檢查點。

2、從運行應用程序的驅動程序故障中恢復 

      元數據檢查點用於恢復進度信息。

如何配置檢查點

  可以通過在容錯,可靠的文件系統(例如,HDFS,S3等)中設置目錄來啓用檢查點,將檢查點信息保存到該目錄中。這是通過使用streamingContext.checkpoint(checkpointDirectory)完成。

此外,如果要使應用程序從驅動程序故障中恢復,則需要使用StreamingContext.getOrCreate進行如下操作:

  • 程序首次啓動時,它將創建一個新的StreamingContext,設置所有流,然後調用start()。
  • 失敗後重新啓動程序時,它將根據檢查點目錄中的檢查點數據重新創建StreamingContext。
def functionToCreateContext(): StreamingContext = {
  val ssc = new StreamingContext(...)   // new context
  val lines = ssc.socketTextStream(...) // create DStreams
  ...
  ssc.checkpoint(checkpointDirectory)   // set checkpoint directory
  ssc
}
val checkpointPath = ......
val context = StreamingContext.getOrCreate(checkpointPath, functionToCreateContext _)

// Start the context
context.start()
context.awaitTermination()

如果checkpointDirectory存在,則將根據檢查點數據重新創建上下文。如果該目錄不存在(即首次運行),則將functionToCreateContext調用該函數以創建新上下文並設置DStreams。

    請注意,RDD的檢查點會導致保存到可靠存儲的成本。這可能會導致RDD被檢查點的那些批次的處理時間增加。因此,需要仔細設置檢查點的間隔。在小批量(例如1秒)時,每批檢查點可能會大大降低操作吞吐量。相反,檢查點太少會導致沿襲和任務規模增加,這可能會產生不利影響。對於需要RDD檢查點的有狀態轉換,默認間隔爲批處理間隔的倍數,至少應爲10秒。可以使用設置 dstream.checkpoint(checkpointInterval),通常,設置爲DStream的duration的5-10倍時間。

定時checkpoint

val messages = KafkaUtils.createDirectStream[String,String,StringDecoder,StringDecoder](ssc,kafkaParams, topics)
//設置檢查點目錄
ssc.checkpoint(checkpointPath)
//定時checkpoint
messages.checkpoint(Duration(8*10.toInt*1000))

messages.....
      

 何時啓動checkpoint操作

    在 Spark Streaming 中,JobGenerator 用於生成每個 batch 對應的 jobs,它有一個定時器,定時器的週期即初始化 StreamingContext 時設置的 batchDuration。這個週期一到,JobGenerator 將調用generateJobs方法來生成並提交 jobs,這之後調用 doCheckpoint 方法來進行 checkpoint。doCheckpoint 方法中,會判斷當前時間與 streaming application start 的時間之差是否是 checkpoint duration 的倍數,只有符合條件的情況下才進行 checkpoint。


    最終 checkpoint 的形式是將類 Checkpoint的實例序列化後寫入外部存儲,值得一提的是,有專門的一條線程來做將序列化後的 checkpoint 寫入外部存儲。除了 Checkpoint 類,還有 CheckpointWriter 類用來導出 checkpoint,CheckpointReader 用來導入 checkpoint。

checkpoint對象主要包括內容

val master = ssc.sc.master
val framework = ssc.sc.appName
val jars = ssc.sc.jars
val graph = ssc.graph
val checkpointDir = ssc.checkpointDir
val checkpointDuration = ssc.checkpointDuration
val pendingTimes = ssc.scheduler.getPendingTimes().toArray
val sparkConfPairs = ssc.conf.getAll

使用checkpoint存在的坑

1、

checkpoint保存的數據是由checkpoint類序列化後存儲的數據。如果我們的Application程序重新編譯之後,再次使用之前的checkpoint文件(即反序列化文件內容)的時候會報錯。

原因:checkpoint的元數據會記錄jar序列化的二進制文件,代碼改變重新編譯後,jar文件改變,checkpoint識別不到,所以報錯。

解決方法:在checkpoint目錄中,刪除以checkpoint開頭的文件

2、數據操作邏輯不要寫在main方法中

而是寫在function2CreateStreamingContext方法中

def function2CreateStreamingContext()={
......
}
val ssc =StreamingContext.getOrCreate(checkpointPath,function2CreateStreamingContext)
ssc.start()
ssc.awaitTermination()

參考文章:https://blog.csdn.net/yjgithub/article/details/78792616

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