SparkStreaming從入門到放棄(三)

本文主要講解Dstream 如何生成RDD以及如何驅動RDD的調用的?

(1)從Dstream.print()開始

將數據打印出來,取前面幾條,最後調用的是:

而regester中是直接將結果作爲輸出ssc.graph.addOutputStream(this)

上一節中我們知道,JobGenertor會掉用generatedJob來定期啓動time調用job.

也就是說,是 DStreamGraph 繼續調用了每 outputStream  generateJob(time) 方法 —— 而我們知道,只有 ForEachDStream outputStream,所以將調用 ForEachDStream  generateJob(time) 方法.比如調用print的時候會調用ForeachDstream的generatoeJob,其中會調用parent.getOrCompute(time)àcomputer(time)方法,compute(time) 的具體實現裏,就很簡單了:

  • (1) 獲取 parent DStream 在本 batch 裏對應的 RDD 實例
  • (2) 以這個 parent RDD 和本次 batch 的 time 爲參數,調用 foreachFunc(parentRDD, time) 方法

(2)上面是action的流程,對於transformation又是如何的?

MappedDstream的compute方法

override def compute(validTime: Time): Option[RDD[U]] = {

    parent.getOrCompute(validTime).map(_.map[U](mapFunc))

  }

可以看到,首先在構造函數裏傳入了兩個重要內容:

  • parent,是本 MappedDStream 上游依賴的 DStream
  • mapFunc,是本次 map() 轉換的具體函數
    • 在前文 [DStream, DStreamGraph 詳解](1.1 DStream, DStreamGraph 詳解.md) 中的 quick example 裏的 val pairs = words.map(word => (word, 1)) 的 mapFunc 就是 word => (word, 1)

獲取了parent dstream的rdd實例,然後以mapFun爲參數調用 .map(mapFunc) 方法,將得到的新 RDD 實例返.

(3)對於inputstream又是如何的?

可以看到生成的是BlockRdd.

這樣串起來了,inputstream生成BlockRddtransfermationRDD轉換,action實現對數據的輸出。

總結:

我們在代碼裏的兩次 print() 操作產生了兩個 ForEachDStream 節點 x  y,兩次調用 x.generateJob(time)  y.generateJob(time) 

 x  parentDStream.getOrCompute(time), d.getOrCompute(time); d.getOrCompute(time) 會牽扯 c.getOrCompute(time),乃至 a.getOrCompute(time)b.getOrCompute(time)

y 節點生成 Job 的過程,與 x 節點的過程非常類似,只是在 b.getOrCompute(time) 時,會命中 get(time) 而不需要觸發 compute(time) 了,這是因爲該 RDD 實例已經在 x 節點的生成過程中被實例化過一次,所以在這裏只需要取出來用就可以

整個鏈條就串起來了!

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