一、定義
Spark Streaming 是 Spark 的流式數據處理模塊。Spark Streaming 支持的數據輸入源有很多,例如:Kafka、Flume、Twitter、ZeroMQ 和簡單的 TCP 套接字等。
二、DStream 和 Structured Streaming
Spark Streaming 使用離散化流(DStream)作為基本抽象。DStream 是一系列連續的 RDD,每個 RDD 代表一段時間內收集的數據。在 Spark Streaming 中,數據流被分成一系列批次,每個批次處理一段時間內的數據。
除了 DStream,Spark Streaming 還支持結構化流(Structured Streaming),這是從 Spark 2.0 開始引入的更高層次的 API。結構化流使用 DataFrame 和 Dataset API,並提供了更簡單的編程模型和更好的性能。
2.1 離散化流(DStream)
2.1.1 核心概念
- 本質:一個 DStream 本質上是一系列連續的 RDD。每個 RDD 包含一個特定時間間隔內到達的數據。
- 時間片:Spark Streaming 將實時數據流按時間切分成小的批次(例如 1 秒或 2 秒)。每個批次的數據對應一個 RDD。
- 不可變性:和 RDD 一樣,DStream 也是不可變的。任何轉換操作都會生成一個新的
- 操作類型:DStream 提供了許多與 RDD 相似的操作,如 map、reduce、join 等,同時還提供了與時間相關的操作,如滑動窗口操作。
2.1.2 創建方式
// 方式1:通過 SparkConf 創建
val conf = new SparkConf().setAppName("StreamingApp").setMaster("local[2]")
val ssc = new StreamingContext(conf, Seconds(5)) // 5秒批處理間隔
// 方式2:通過已有的 SparkContext 創建
val sc = new SparkContext(conf)
val ssc = new StreamingContext(sc, Seconds(5))
2.1.3 特點
- 優點:
- 基於成熟的 RDD 模型,與 Spark Core 緊密結合。
- 提供細粒度的控制,特別是通過
foreachRDD。
- 缺點:
- 處理延遲較高:因為是微批次處理,延遲通常在秒級。
- API 級別較低:開發者需要自己處理與時間相關的邏輯(如事件時間、延遲數據)。
- 不感知執行計劃:無法像 DataFrame 一樣進行 Catalyst 優化。
2.2 結構化流(Structured Streaming)
2.2.1 核心概念
- 結構化流是構建在 Spark SQL 引擎上的流處理引擎,使用 Dataset/DataFrame API。
- 它將實時數據流視為一張無界表,新的數據不斷追加到這張表中。
- 支持基於事件時間的處理、水位線(watermark)處理延遲數據、以及容錯狀態管理。
- 輸出模式包括追加模式、更新模式和完整模式。
2.2.2 創建方式
// 使用 SparkSession(與 Spark SQL 相同)
val spark = SparkSession.builder()
.appName("StructuredStreamingApp")
.master("local[2]")
.config("spark.sql.streaming.schemaInference", "true")
.config("spark.sql.streaming.checkpointLocation", "/checkpoint/path")
.getOrCreate()
2.2.3 關鍵特性
- 事件時間與水位線
- 事件時間:數據本身產生的時間戳,而不是到達系統的時間。這對於處理亂序和延遲的數據至關重要。
- 水位線:一個機制,用於告訴 Spark 可以“等待”延遲數據多久。當處理基於事件時間的窗口時,水位線讓引擎可以跟蹤當前處理的事件時間,並自動清理舊的狀態。
- 輸出模式
- Append 模式:只將窗口中最終的結果輸出一次。這是默認模式。
- Update 模式:以增量方式輸出,每當一條記錄被更新就輸出一次。
- Complete 模式:每次觸發後,輸出完整的計算結果(適用於有狀態操作,如聚合)。
- 端到端 exactly-once 語義
Structured Streaming 通過與源端和輸出端的集成,可以保證在發生故障時,每條記錄被精確處理一次,不丟不重。
2.3 總結對比
|
特性
|
DStream (微批次)
|
Structured Streaming
|
|
編程模型 |
基於 RDD 的低級 API
|
基於 DataFrame/Dataset 的高級聲明式 API
|
|
API 級別 |
較低級,需手動處理狀態、窗口
|
較高級,內置對事件時間、窗口、水位線的支持
|
|
性能優化 |
無自動優化
|
利用 Spark SQL 的 Catalyst 優化器和 Tungsten 執行引擎
|
|
延遲 |
秒級(微批次)
|
可達毫秒級(微批次),還有更低延遲的連續處理模式
|
|
語義保證 |
At-least-once 或 exactly-once(需精心設計)
|
端到端的 Exactly-once 語義 |
|
學習曲線 |
需要理解 RDD 和流處理概念
|
對於熟悉 Spark SQL 的開發者更簡單
|
|
推薦程度 |
遺留系統,需要極細粒度控制時使用 |
新項目的首選,功能更強大,開發更簡單 |
三、Spark Streaming 架構
3.1 架構圖
3.2 背壓機制
在 Spark 1.5 之後,引入了背壓機制。系統能夠自動根據當前的處理能力動態調整接收數據的速率,防止在流量高峯時內存被撐爆。根據 Job Scheduler 反饋作業的執行信息來動態調整 Receiver 數據接收速率。
通過屬性“spark.streaming.backpressure.enabled”來控制是否啓用 backpressure 機制,默認值 false,即不啓用。