Spark Streaming簡單入門(示例+原理)

mcxiaoracle發表於2022-07-12

SparkStreaming是流式處理框架,是Spark API的擴充套件,支援可擴充套件、高吞吐量、容錯的實時資料流處理,實時資料的來源可以是:Kafka, Flume, Twitter, ZeroMQ或者TCP sockets,並且可以使用高階功能的複雜運算元來處理流資料。例如:map,reduce,join,window 。最終,處理後的資料可以存放在檔案系統,資料庫等,方便實時展現。



讓我們從建立StreamingContext 開始,它是流計算功能的主要入口。StreamingContext 會在底層建立出SparkContext,用來處理資料。其建構函式還接收用來指定多長時間處理一次新資料的批次間隔(batch interval)作為輸入,這裡我們把它設為1 秒。


到此時只是設定好了要進行的計算步驟,系統收到資料時計算就會開始。要開始接收資料,必須顯式呼叫StreamingContext 的start() 方法。這樣,Spark Streaming 就會開始把Spark 作業不斷交給下面的SparkContext 去排程執行。執行會在另一個執行緒中進行,所以需要呼叫awaitTermination 來等待流計算完成,來防止應用退出。


// 啟動流計算環境StreamingContext並等待它"完成"

ssc.start()

// 等待作業完成

ssc.awaitTermination()


下面結合程式碼逐一分析SparkStreaming應用執行的過程


在Driver端中,StreamingContext初始化時會建立一些內部的關鍵元件如DStreamGraph、ReceiverTracker、JobGenerator和JobScheduler等。實際上,呼叫StreamingContext.start()方法的時候,就會在Spark叢集中的某個Worker節點上的Executor,啟動輸入DStream的Receiver。



Receiver負責從外部資料來源接收資料,Receiver接收到資料之後,會啟動一個BlockGenerator,其會每隔一段時間(可配置,預設是200ms)將Receiver接收到的資料,打包成一個block,每個block除了會儲存到所執行的Executor關聯的BlockManager中之外,還會傳送一份block資訊如blockId到Driver端的ReceiverTracker上,其會將一個一個的block資訊存入一個HashMap中,key就是時間。



記下來,JobGenerator會每隔我們定義的batch時間間隔,就會去ReceiverTracker中獲取經過這個batch時間間隔內的資料資訊blocks,將這些block聚合成一個batch,然後這個batch會被建立為一個RDD。


這樣每隔一個batch時間間隔,都會將在這個時間間隔內接收的資料形成一個RDD,這樣就會產生一個RDD序列,每個RDD代表資料流中一個時間間隔內的資料。正是這個RDD序列,形成SparkStreaming應用的輸入DStream。


從宏觀來說,Spark Streaming 使用“微批次”的架構,把流式計算當作一系列連續的小規模批處理來對待。Spark Streaming 從各種輸入源中讀取資料,並把資料分組為小的batch。新的batch按均勻的時間間隔建立出來。在每個時間區間開始的時候,一個新的batch就建立出來,在該區間內收到的資料都會被新增到這個batch中。在時間區間結束時,batch停止增長。時間區間的大小是由batch間隔這個引數決定的。batch間隔一般設在500 毫秒到幾秒之間,由應用開發者配置。每個輸入batch都形成一個RDD,以Spark 作業的方式處理並生成其他的RDD。處理的結果可以以批處理的方式傳給外部系統。




StreamingContext初始化後,包括Receiver啟動後,再到生成輸入DStream,就完成了SparkStreaming應用程式的準備工作。


DStream的轉化操作


在建立好輸入DStream後,對其呼叫了filter()運算元,filter()運算元是轉化操作,會將操作應用到DStream的每一個RDD。


需要記住的是,儘管這些函式看起來像作用在整個流上一樣,但事實上每個DStream 在內部是由許多RDD(批次)組成,且這些轉化操作是分別應用到每個RDD 上的。例如,filter()會對DStream內的每個時間區間的資料(RDD)進行過濾,reduceByKey() 會歸約每個RDD中的資料,但不會歸約不同區間之間的資料。



對於本文的示例,對輸入DStream作filter操作後生成新的DStream的過程如下:

Spark Streaming允許DStream的資料輸出到外部系統,如資料庫或檔案系統,輸出的資料可以被外部系統所使用,該操作類似於RDD的輸出操作。


在Spark核心中,作業是由一系列具有依賴關係的RDD及作用於這些RDD上的運算元函式所組成的操作鏈。在遇到行動操作時觸發執行,向DAGScheduler提交併執行作業。Spark Streaming中作業的生成與Spark核心類似,對DStream進行的各種操作讓它們之間構建起依賴關係。


當遇到DStream使用輸出操作時,這些依賴關係以及它們之間的操作會被記錄到名為DStreamGraph的物件中表示一個job。這些job註冊到DStreamGraph並不會立即執行,而是等到Spark Streaming啟動後,到達批處理時間時,才根據DSteamGraph生成job處理該批處理時間內接收的資料。在Spark Streaming如果應用程式中存在多個輸出操作,那麼在批處理中會產生多個job。



與RDD中的惰性求值類似,如果一個DStream及其派生出的DStream都沒有被執行輸出操作,那麼這些DStream就都不會被求值。如果StreamingContext中沒有設定輸出操作,整個context就都不會啟動。


常用的一種除錯性輸出操作是print(),它會在每個批次中抓取DStream的前十個元素列印出來。


總體來說,Spark Streaming是將流式計算分解成一系列短小的批處理作業。這裡的批處理引擎是Spark Core,也就是Spark Streaming將輸入資料按照batch interval(如5秒)分成一段一段的資料(Discretized Stream),每一段資料都轉換成Spark中的RDD(Resilient Distributed Dataset),然後將Spark Streaming中對DStream的Transformation操作變為針對DSteam內各個RDD的Transformation操作,將RDD經過操作變成中間結果儲存在記憶體中。整個流式計算根據業務的需求可以對中間的結果進行疊加或者儲存到外部裝置


假設batchInterval = 5s, SparkStreaming啟動之後,0-5s內一直接受資料,假設SparkStreaming處理這一個批次資料的時間是3s,那麼5-8s內一邊接收新資料(開始第二批次),同時會觸發DStream的job執行,這時會啟動另一個執行緒處理第一批次的資料;8-10s內只是接收資料(還是第二批次);10-13s內一邊接收新資料(開始第三批次),一邊處理第二批次的資料,然後13-15s只是接收資料(還是第三批次),如此往復進行資料的接收與處理。


SparkStreaming進行流資料處理大致可以分為:啟動流處理引擎、接收及儲存流資料、處理流資料和輸出處理結果等4個步驟,其執行架構如下

(1) 初始化StreamingContext物件,在該物件啟動過程中例項化DStreamGraph和JobScheduler,其中DStreamGraph用於存放DStream以及DStream之間的依賴關係等資訊,而JobScheduler中包括ReceiverTracker和JobGenerator。其中ReceiverTracker為Driver端流資料接收器(Receiver)的管理者,JobGenerator為批處理作業生成器。在ReceiverTracker啟動過程中,根據流資料接收器分發策略通知對應的Executor中的流資料接收管理器(ReceiverSupervisor)啟動,再由ReceiverSupervisor啟動流資料接收器Receiver。


(2) 當流資料接收器Receiver啟動後,持續不斷地接收實時流資料,根據傳過來資料的大小進行判斷,如果資料量很小,則攢多條資料成一塊,然後再進行塊儲存;如果資料量大,則直接進行塊儲存。對於這些資料Receiver直接交給ReceiverSupervisor,由其進行資料轉儲操作。塊儲存根據是否設定預寫日誌分為兩種,一種是使用非預寫日誌BlockManagerBasedBlockHandler方法直接寫到Worker的記憶體或磁碟中,另一種是進行預寫日誌WriteAheadLogBasedBlockHandler方法,即在預寫日誌同時把資料寫入到Worker的記憶體或磁碟中。資料儲存完畢後,ReceiverSupervisor會把資料儲存的元資訊上報給ReceiverTracker,ReceiverTracker再把這些資訊轉發給ReceiverBlockTracker,由它負責管理收到的資料塊的元資訊。


(4) 在Spark核心的作業隊資料進行處理,處理完畢後輸出到外部系統,如資料庫或檔案系統,輸出的資料可以被外部系統所使用。 由於實時流資料的資料來源源不斷地流入,Spark會週而復始地進行資料處理,相應地也會持續不斷地輸出結果。








————————————————

推薦閱讀:

https://blog.csdn.net/u012369535/article/details/93042905


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69949806/viewspace-2905247/,如需轉載,請註明出處,否則將追究法律責任。

相關文章