SparkStreaming
Spark Streaming類似於Apache Storm,用於流式數據的處理。Spark Streaming有高吞吐量和容錯能力強等特點。Spark Streaming支持的數據源有很多,例如:Kafka、Flume、Twitter、ZeroMQ和簡單的TCP套接字等等。數據輸入後可以用Spark的高度抽象操作如:map、reduce、join、window等進行運算。而結果也能保存在很多地方,如HDFS,數據庫等。
特性
1、易用性
可以像編寫離線批處理一樣去開發流式的處理程序,並且可以使用java/scala/Python語言進行代碼開發
2、容錯性
SparkStreaming在沒有額外代碼和配置的情況下可以恢復丟失的工作。
3、可以融合到spark生態系統
sparkStreaming流式處理可以跟批處理和交互式查詢相結合
與storm對比
storm是來一條數據處理一條數據,SparkStreaming是以某一時間間隔批量處理數據。
SparkStreaming原理
Spark Streaming 是基於spark的流式批處理引擎,核心是採用微批次架構,即把輸入數據以某一時間間隔批量的處理,當批處理間隔縮短到秒級時,便可以用於處理實時數據流。
計算流程
Spark Streaming是將流式計算分解成一系列短小的批處理作業。這裏的批處理引擎是Spark Core,也就是把Spark Streaming的輸入數據按照batch size(如1秒)分成一段一段的數據(Discretized Stream),
每一段數據都轉換成Spark中的RDD(Resilient Distributed Dataset),然後將Spark Streaming中對DStream的Transformation操作變爲針對Spark中對RDD的Transformation操作,
將RDD經過操作變成中間結果保存在內存中。整個流式計算根據業務的需求可以對中間的結果進行緩存或者存儲到外部設備。下圖顯示了Spark Streaming的整個流程。
容錯性
對於流式計算來說,容錯性至關重要。首先我們要明確一下Spark中RDD的容錯機制。每一個RDD都是一個不可變的分佈式可重算的數據集,其記錄着確定性的操作繼承關係(lineage),所以只要輸入數據是可容錯的,那麼任意一個RDD的分區(Partition)出錯或不可用,都是可以利用原始輸入數據通過轉換操作而重新算出的。
實時性
對於實時性的討論,會牽涉到流式處理框架的應用場景。Spark Streaming將流式計算分解成多個Spark Job,對於每一段數據的處理都會經過Spark DAG(有向無環圖)圖分解以及Spark的任務集的調度過程。 對於目前版本的Spark Streaming而言,其最小的Batch Size的選取在0.5~2秒鐘之間(Storm目前最小的延遲是100ms左右), 所以Spark Streaming能夠滿足除對實時性要求非常高(如高頻實時交易)之外的所有流式準實時計算場景。
DStream
Discretized Stream是Spark Streaming的基礎抽象,代表持續性的數據流和經過各種Spark算子操作後的結果數據流。在內部實現上,DStream是一系列連續的RDD來表示。每個RDD含有一段時間間隔內的數據,如下圖:
對數據的操作也是按照RDD爲單位來進行的
Spark Streaming使用數據源產生的數據流創建DStream,也可以在已有的DStream上使用一些操作來創建新的DStream。
它的工作流程像下面的圖所示一樣,接受到實時數據後,給數據分批次,然後傳給Spark Engine處理最後生成該批次的結果。
DStream相關操作
DStream上的操作與RDD的類似,分爲Transformations(轉換)和Output Operations(輸出)兩種,此外轉換操作中還有一些比較特殊的操作,如:updateStateByKey()、transform()以及各種Window相關的操作。
Transformations on DStreams
Transformation |
Meaning |
map(func) |
對DStream中的各個元素進行func函數操作,然後返回一個新的DStream |
flatMap(func) |
與map方法類似,只不過各個輸入項可以被輸出爲零個或多個輸出項 |
filter(func) |
過濾出所有函數func返回值爲true的DStream元素並返回一個新的DStream |
repartition(numPartitions) |
增加或減少DStream中的分區數,從而改變DStream的並行度 |
union(otherStream) |
將源DStream和輸入參數爲otherDStream的元素合併,並返回一個新的DStream. |
count() |
通過對DStream中的各個RDD中的元素進行計數,然後返回只有一個元素的RDD構成的DStream |
reduce(func) |
對源DStream中的各個RDD中的元素利用func進行聚合操作,然後返回只有一個元素的RDD構成的新的DStream. |
countByValue() |
對於元素類型爲K的DStream,返回一個元素爲(K,Long)鍵值對形式的新的DStream,Long對應的值爲源DStream中各個RDD的key出現的次數 |
reduceByKey(func, [numTasks]) |
利用func函數對源DStream中的key進行聚合操作,然後返回新的(K,V)對構成的DStream |
join(otherStream, [numTasks]) |
輸入爲(K,V)、(K,W)類型的DStream,返回一個新的(K,(V,W))類型的DStream |
cogroup(otherStream, [numTasks]) |
輸入爲(K,V)、(K,W)類型的DStream,返回一個新的 (K, Seq[V], Seq[W]) 元組類型的DStream |
transform(func) |
通過RDD-to-RDD函數作用於DStream中的各個RDD,可以是任意的RDD操作,從而返回一個新的RDD |
updateStateByKey(func) |
根據key的之前狀態值和key的新值,對key進行更新,返回一個新狀態的DStream |
特殊的Transformations:
updateStateByKey 用於記錄歷史記錄,保存上次的狀態
reduceByKeyAndWindow 開窗函數
Output Operations on DStreams
相當於rdd的action的作用,transformation不會立即執行,到這纔會執行
Output Operation |
Meaning |
print() |
打印到控制檯 |
saveAsTextFiles(prefix, [suffix]) |
保存流的內容爲文本文件,文件名爲 "prefix-TIME_IN_MS[.suffix]". |
saveAsObjectFiles(prefix, [suffix]) |
保存流的內容爲SequenceFile,文件名爲 "prefix-TIME_IN_MS[.suffix]". |
saveAsHadoopFiles(prefix, [suffix]) |
保存流的內容爲hadoop文件,文件名爲 "prefix-TIME_IN_MS[.suffix]". |