Spark Streaming基礎簡介
批量計算和流計算
首先什麼是靜態資料和流資料?很多企業為了支援決策分析而構建的資料倉庫系統,其中存放的大量歷史資料就是靜態資料。而流資料即資料以大量、快速、時變的流形式持續到達。
對於靜態資料和流資料的處理,對應著兩種截然不同的計算模式:批量計算和流計算
- 批量處理:充裕時間處理靜態資料,如Hadoop。Hadoop設計的初衷是面向大規模資料的批量處理,每臺機器並行執行MapReduce任務,最後對結果進行彙總輸出。
- 流計算:實時獲取來自不同資料來源的海量資料,經過實時分析處理,獲得有價值的資訊。
流資料不適合採用批量計算,因為流資料不適合用傳統的關係模型建模。流資料必須採用實時計算,響應時間為秒級。
流計算秉承一個基本理念,即資料的價值隨著時間的流逝而降低,如使用者點選流。因此,當事件出現時就應該立即進行處理,而不是快取起來進行批處理。為了及時處理流資料,就需要一個低延遲、可擴充套件、高可高的處理引擎。
對於一個流計算系統來說,它應達到如下需求:
- 高效能:處理大資料的基本要求,如每秒處理幾十萬條資料
- 海里式:支援TB級甚至是PB級的資料規模
- 實時性:保證較低的延遲時間,達到秒級別,甚至是毫秒級別
- 分散式:支援大資料的基本架構,必須能夠平滑擴充套件
- 易用性:能夠開速進行開發和部署
- 可靠性:能可靠地處理流資料
流計算處理流程
流計算的處理流程一般包含三個階段:資料實時採集、資料實時計算、實時查詢服務。
- 資料實時採集
資料實時採集階段通常採集多個數據源的海量資料,需要保證實時性、低延遲與穩定可靠。
以日誌資料為例,由於分散式叢集的廣泛應用,資料分散儲存在不同的機器上,因此需要實時彙總來自不同機器上的日誌資料。目前有許多網際網路公司釋出的開源分散式日誌採集系統均可滿足每秒數百MB的資料採集和傳輸需求,如:
- Facebook的Scribe
- LinkedIn的Kafka
- 淘寶的Time Tunnel
- 基於Hadoop的Chukwa和Flume
資料實時計算
資料實時計算階段對採集的資料進行實時的分析和計算,並反饋實時結果。經流處理系統處理後的資料,可視情況進行儲存,一便之後再進行分析計算。在實效性要求較高的場景中,處理之後的資料也可以直接丟棄。實時查詢服務
經由流計算框架得出的結果可供使用者進行實時查詢、展示或儲存。
傳統的資料處理流程,使用者需要主動發出查詢才能獲得想要的結果。而在流處理過程中,實時查詢服務可以不斷更新結果,並將使用者所需要的結果實時推送給使用者。
雖然通過對傳統的資料處理系統你那個進行定時查詢,也可以出現不斷更新結果和結果推送,但通過這樣的方式獲取的結果,仍然是根據過去某一時刻的資料得到的結果,與實時結果有著本質的區別。
可見,流例項系統與傳統的資料處理系統有如下不同:
- 流處理系統處理的是實時的資料,而傳統的資料處理系統處理的是預先儲存好的靜態資料
- 使用者通過流處理系統獲取的是實時結果,而通過傳統的資料處理系統,獲取的是過去某一時刻的結果
- 流處理系統無需使用者主動發出查詢,實時查詢服務可以主動將實時結果推送給使用者
Spark Streaming
Spark Streaming設計
Spark Streaming可整合多種輸入資料來源,如Kafka、Flume、HDFS,甚至是普通的TCP套接字。經處理後的資料儲存至檔案系統、資料庫,或顯示在儀表盤裡。
Spark Streaming的基本原理是將實時輸入資料流以時間片(秒級)為單位進行拆分,然後經Spark引擎以類似批處理方式處理每個事件片資料。
Spark Streaming最主要的抽象是DStream(Discretized Stream, 離散化資料流),表示連續不斷的資料流。在內部實現上,Spark Streaming的輸入資料按照時間片(如1秒)分成一段一段,每一段資料轉換為Spark中的RDD,這些分段就是Dstream,並且對DStream的操作都最終轉變為對相應的RDD的操作。
Spark Streaming與Storm
Spark Streaming和Storm最大的區別在於,Spark Streaming無法實現毫秒級的流計算,而Storm可以實現毫秒級響應
Spark Streaming構建在Spark上,一方面是因為Saprk的低延遲執行引擎(100ms+)可以用於實時計算,另一方面,相比於Storm,RDD資料集更容易做高效的容錯處理。
Spark Streaming採用的小批量處理的方式使得它可以同時相容批量和實時資料處理的邏輯和演算法,因此,方便了一些需要歷史資料和實時資料聯合分析的特定應用場合。
Spark Streaming工作原理
在Spark中,一個應用(Application)由一個任務控制節點(Driver)和若干個作業(Job)構成,一個作業由多個階段(Stage)構成,一個階段由多個任務(Task)組成。
當執行一個應用時,任務控制節點會向叢集管理器(Cluster Manger)申請資源,啟動Executor,並向Executor傳送應用程式程式碼和檔案,然後在Executor上執行Task。
在Spark Streaming中,會有一個元件Receiver,作為一個長期執行的task跑在一個Executor上。每個Receiver都會負責一個input DStream(比如從檔案中讀取資料的檔案流,比如套件字流,或者從Kafka中讀取的一個輸入流等等)。
Spark Streaming通過input DStream與外部資料來源進行連線,讀取相關資料。
編寫Spark Streaming程式的基本步驟是:
- 通過建立輸入DStream來定義輸入源。
- 通過對DStream應用轉換操作和輸出操作來丁意思流計算
- 用streamingContext.start()來開始接收資料和處理流程
- 通過streamingContext.awaitTermination()方法來等待處理結束(手動結束或因為錯誤而結束)
- 可以通過streamingContext.stop()來手動結束流計算程序
如果要執行一個Spark Streaming程式,就需要首先生成一個StreamingContext物件,它是Spark Streaming程式的主入口。可以從一個SparkConf物件建立一個StreamingContext物件。
在Linux系統中,啟動spark-shell,進入spark-shell以後,就已經獲得了一個預設的SpakrContext,也就是sc。因此,可以採用如下方式來建立StreamingContext物件:
improt org.apache.spark.steraming._
val ssc = new StreamingContext(sc, Seconds(1))
如果是編寫一個獨立的Spark Streaming程式,而不是在spark-shell中執行,則需要通過如下方式建立StreamingContext物件:
import org.apache.spakr._
import org.apache.spark.streaming._
val conf = new SaprkConf(),setAppName("TestDStream").setMaster("local[2]")
val ssc = new SteamingContext(conf, Seconds(1))