Spark 之 Streaming 學習筆記整理

概述

關於 Spark Streaming

Spark Streaming 類似於 Apache Storm,用於流式數據的處理。官方文檔介紹,Spark Streaming 有高吞吐量和容錯能力強等特點。Spark Streaming 支持的數據輸入源很多,例如:Kafka、Flume、Twitter、ZeroMQ 和簡單的 TCP 套接字等等。數據輸入後可以用 Spark 的高度抽象原語如:map、reduce、join、window 等進行運算。而結果也能保存在很多地方,如 HDFS,數據庫等。另外 Spark Streaming 也能和 MLlib(機器學習)以及 Graphx 完美融合。

Spark 的各個子框架,都是基於核心 Spark 的,Spark Streaming 在內部的處理機制是,接收實時流的數據,並根據一定的時間間隔拆分成一批批的數據,然後通過 Spark Engine 處理這些批數據,最終得到處理後的一批批結果數據。對應的批數據,在 Spark 內核對應一個 RDD實例,因此,對應流數據的 DStream 可以看成是一組 RDDs,即 RDD 的一個序列。通俗點理解的話,在流數據分成一批一批後,通過一個先進先出的隊列,然後 Spark Engine 從該隊列中依次取出一個個批數據,把批數據封裝成一個RDD,然後進行處理,這是一個典型的生產者消費者模型,對應的就有生產者消費者模型的問題,即如何協調生產速率和消費速率。

總結:Spark Streaming 的基本原理是將輸入數據流以時間片(秒級)爲單位進行拆分,然後以類似批處理的方式處理每個時間片數據

爲什麼學習 Spark Streaming

  1. 易用
  2. 容錯
  3. 易整合到 spark 體系

Spark Streaming 和 Storm 對比

Spark Streaming Storm
開發語言:scala,java 開發語言:clojure,java 等
源碼:scala 源碼:clojure
編程模型:DStream 編程模型:Spout/Bolt
延遲:一定的延時,僞實時 延遲:亞秒級

總結:

1、延遲和吞吐量
Storm:
    低延遲的,一次處理一條數據,真正意義上的實時處理。吞吐量小一點。
SparkStreaming:
    微批處理,稍微有一些延遲性,一次處理的是一批數據,其實不是真正意義上的實時處理,準實時處理。吞吐量要大一點。

2、容錯性
SparkStreaming: 
    容錯性做得非常好。Driver,Executor,Receiver,Task,Block 數據丟失怎麼辦?(RDD)
Storm:
    storm 的容錯是基於 ack 組件完成。開銷要比 SparkSreaming 大

核心概念

1、離散流(discretized stream)或 DStream:這是 Spark Streaming 對內部持續的實時數據流的抽象描述,即我們處理的一個實時數據流,在 Spark Streaming 中對應於一個 DStream 實例。

2、批數據(batch data):這是化整爲零的第一步,將實時流數據以時間片爲單位進行分批,將流處理轉化爲時間片數據的批處理。隨着持續時間的推移,這些處理結果就形成了對應的結果數據流了。

3、時間片或批處理時間間隔(batch interval):這是人爲地對流數據進行定量的標準,以時間片作爲我們拆分流數據的依據。一個時間片的數據對應一個 RDD 實例。

4、窗口長度(window length):一個窗口覆蓋的流數據的時間長度。必須是批處理時間間隔的倍數

5、滑動時間間隔:前一個窗口到後一個窗口所經過的時間長度。必須是批處理時間間隔的倍數

6、Input DStream:一個 InputDStream 是一個特殊的 DStream,將 Spark Streaming 連接到一個外部數據源來讀取數據。

什麼是DStream

Discretized Stream 是 Spark Streaming 的基礎抽象,代表持續性的數據流和經過各種 Spark 原語操作後的結果數據流。在內部實現上,DStream 是一系列連續的 RDD 來表示。DStream 是連續數據的離散化表示,DStream 中每個離散片段都是一個 RDD,DStream 可以變換成另一個 DStream。

每個 RDD 含有一段時間間隔內的數據

對數據的操作也是按照 RDD 爲單位來進行的(計算過程由 Spark Engine 來完成)

DStream 相關操作

DStream 上的原語與 RDD 的類似,分爲 Transformations(轉換)和 Output Operations(輸出,和 RDD 的 action 操作類似)兩種,此外轉換操作中還有一些比較特殊的原語,如:updateStateByKey()、transform()以及各種 window()相關的原語。

Transformations on Dstream

特殊的 Transformations

  1. UpdateStateByKey Operation
  2. Transform Operation
  3. Window Operations

(具體用法和細節參考官網或者搜相關博客,此處省略待後續整理)

Output Operations on Dstream

Output Operations 可以將 DStream 的數據輸出到外部的數據庫或文件系統,當某個 Output Operations 原語被調用時(與 RDD 的 Action 相同),Streaming 程序纔會開始真正的計算過程。

StreamingContext 

在 Spark Streaming 當中,StreamingContext 是整個程序的入口,其創建方式有多種,最常用的是通過 SparkConf 來創建:

package com.mazh.spark.streaming
import org.apache.spark.SparkConf
import org.apache.spark.streaming.{Seconds, StreamingContext}

object StreamingContextTest {
    def main(args: Array[String]): Unit = {
        val sparkConf = new SparkConf().setAppName("SCTest").setMaster("local[4]")
        val streamingContext = new StreamingContext(sparkConf, Seconds(2))
    }
}


源碼中:
/**
 * Create a StreamingContext by providing the configuration necessary for a new 
 * SparkContext.
 * @param conf a org.apache.spark.SparkConf object specifying Spark parameters
 * @param batchDuration the time interval at which streaming data will be divided 
 * into batches
 */
def this(conf: SparkConf, batchDuration: Duration) = {
    this(StreamingContext.createNewSparkContext(conf), null, batchDuration)
}

也就是說 StreamingContext 是對 SparkContext 的封裝,StreamingContext 還有其它幾個構造方法,感興趣的可以瞭解,創建 StreamingContext 時會指定 batchDuration,它用於設定批處理時間間隔,需要根據應用程序和集羣資源情況去設定。

當創建完成 StreamingContext 之後,再按下列步驟進行:

1、通過輸入源創建 InputDStream
2、對 DStream 進行 transformation 和 output 操作,這樣操作構成了後期流式計算的邏輯
3、 通過 streamingContext.start()方法啓動接收和處理數據的流程
4、使用 streamingContext.awaitTermination()方法等待程序結束(手動停止或出錯停止)
5、也可以調用 streamingContext.stop()方法結束程序的運行

關於 StreamingContext 有幾個值得注意的地方:

1、StreamingContext 啓動後,增加新的操作將不起作用。也就是說在 StreamingContext 啓動之前,要定義好所有的計算邏輯
2、StreamingContext 停止後,不能重新啓動。也就是說要重新計算的話,需要重新運行整個程序。
3、在單個 JVM 中,一段時間內不能出現兩個 active 狀態的 StreamingContext
4、當在調用 StreamingContext 的 stop 方法時,默認情況下 SparkContext 也將被 stop 掉,如果希望 StreamingContext 關閉時,能夠保留 SparkContext,則需要在 stop 方法中傳入參數 stopSparkContext=false
5、一個 SparkContext 可以用來創建多個 StreamingContext,只要前一個 StreamingContext已經停止了。

InputDStreams 和 Receivers 

InputDStream 指的是從數據流的源頭接受的輸入數據流,在將來學習的 StreamingWordCount 程序當中,val lines = ssc.textFileStream(args(0)) 就是一種 InputDStream。除文件流外,每個InputDStream 都關聯一個 Receiver 對象,該 Receiver 對象接收數據源傳來的數據並將其保存在內存中以便後期 Spark 處理。

Spark Streaming 提供兩種原生支持的流數據源和自定義的數據源:

1、Basic Sources(基礎流數據源)
    直接通過 StreamingContext API 創建,例如文件系統(本地文件系統及分佈式文件系統)、Socket 連接及 Akka 的 Actor。
2、Advanced Sources(高級流數據源)
    如 Kafka, Flume, Kinesis, Twitter 等,需要藉助外部工具類,在運行時需要外部依賴(下一節內容中介紹)
3、Custom Sources(自定義流數據源)
    Spark Streaming 還支持用戶,它需要用戶定義 receiver

注意:

1、在本地運行 Spark Streaming 時,master URL 不能使用”local”或”local[1] ”,因爲當 Input DStream 與 Receiver(如 sockets, Kafka, Flume 等)關聯時,Receiver 自身就需要一個線程來運行,此時便沒有線程去處理接收到的數據。因此,在本地運行 SparkStreaming 程序時,要使用”local[n]”作爲 master URL,n 要大於 receiver 的數量。

2、在集羣上運行 Spark Streaming 時,分配給 Spark Streaming 程序的 CPU 核數也必須大於receiver 的數量,否則系統將只接受數據,無法處理數據。

Spark Streaming 示例

(待整理)

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