Spark Streaming + Spark SQL 實現配置化ET
Spark Streaming 非常適合ETL。但是其開發模組化程度不高,所以這裡提供了一套方案,該方案提供了新的API用於開發Spark Streaming程式,同時也實現了模組化,配置化,並且支援SQL做資料處理。
前言
傳統的Spark Streaming程式需要:
構建StreamingContext
設定checkpoint
連結資料來源
各種transform
foreachRDD 輸出
通常而言,你可能會因為要走完上面的流程而構建了一個很大的程式,比如一個main方法裡上百行程式碼,雖然在開發小功能上足夠便利,但是複用度更方面是不夠的,而且不利於協作,所以需要一個更高層的開發包提供支援。
如何開發一個Spark Streaming程式
我只要在配置檔案新增如下一個job配置,就可以作為標準的的Spark Streaming 程式提交執行:
{ "test": { "desc": "測試", "strategy": "streaming.core.strategy.SparkStreamingStrategy", "algorithm": [], "ref": [], "compositor": [ { "name": "streaming.core.compositor.kafka.MockKafkaStreamingCompositor", "params": [ { "metadata.broker.list":"xxx", "auto.offset.reset":"largest", "topics":"xxx" } ] }, { "name": "streaming.core.compositor.spark.JSONTableCompositor", "params": [{"tableName":"test"} ] }, { "name": "streaming.core.compositor.spark.SQLCompositor", "params": [{"sql":"select a from test"} ] }, { "name": "streaming.core.compositor.RDDPrintOutputCompositor", "params": [ { } ] } ], "configParams": { } } }
上面的配置相當於完成了如下的一個流程:
從Kafka消費資料
將Kafka資料轉化為表
透過SQL進行處理
列印輸出
是不是很簡單,而且還可以支援熱載入,動態新增job等
特性
該實現的特性有:
配置化
支援多Job配置
支援各種資料來源模組
支援透過SQL完成資料處理
支援多種輸出模組
未來可擴充套件的支援包含:
動態新增或者刪除job更新,而不用重啟Spark Streaming
支援Storm等其他流式引擎
更好的多job互操作
配置格式說明
該實現完全基於 完成,核心功能大概只花了三個小時。
這裡我們先理出幾個概念:
Spark Streaming 定義為一個App
每個Action定義為一個Job.一個App可以包含多個Job
配置檔案結構設計如下:
{ "job1": { "desc": "測試", "strategy": "streaming.core.strategy.SparkStreamingStrategy", "algorithm": [], "ref": [], "compositor": [ { "name": "streaming.core.compositor.kafka.MockKafkaStreamingCompositor", "params": [ { "metadata.broker.list":"xxx", "auto.offset.reset":"largest", "topics":"xxx" } ] } , ], "configParams": { } }, "job2":{ ........ } }
一個完整的App 對應一個配置檔案。每個頂層配置選項,如job1,job2分別對應一個工作流。他們最終都會執行在一個App上(Spark Streaming例項上)。
strategy 用來定義如何組織 compositor,algorithm, ref 的呼叫關係
algorithm作為資料來源
compositor 資料處理鏈路模組。大部分情況我們都是針對該介面進行開發
ref 是對其他job的引用。透過配合合適的strategy,我們將多個job組織成一個新的job
每個元件( compositor,algorithm, strategy) 都支援引數配置
上面主要是解析了配置檔案的形態,並且 已經給出了一套介面規範,只要照著實現就行。
模組實現
那對應的模組是如何實現的?本質是將上面的配置檔案,透過已經實現的模組,轉化為Spark Streaming程式。
以SQLCompositor 的具體實現為例:
class SQLCompositor[T] extends Compositor[T] { private var _configParams: util.List[util.Map[Any, Any]] = _ val logger = Logger.getLogger(classOf[SQLCompositor[T]].getName)//策略引擎ServiceFrameStrategy 會呼叫該方法將配置傳入進來 override def initialize(typeFilters: util.List[String], configParams: util.List[util.Map[Any, Any]]): Unit = { this._configParams = configParams }// 獲取配置的sql語句 def sql = { _configParams(0).get("sql").toString } def outputTable = { _configParams(0).get("outputTable").toString }//執行的主方法,大體是從上一個模組獲取SQLContext(已經註冊了對應的table),//然後根據該模組的配置,設定查詢語句,最後得到一個新的dataFrame.// middleResult裡的T其實是DStream,我們會傳遞到下一個模組,Output模組//params引數則是方便各個模組共享資訊,這裡我們將對應處理好的函式傳遞給下一個模組 override def result(alg: util.List[Processor[T]], ref: util.List[Strategy[T]], middleResult: util.List[T], params: util.Map[Any, Any]): util.List[T] = { var dataFrame: DataFrame = null val func = params.get("table").asInstanceOf[(RDD[String]) => SQLContext] params.put("sql",(rdd:RDD[String])=>{ val sqlContext = func(rdd) dataFrame = sqlContext.sql(sql) dataFrame }) middleResult } }
上面的程式碼就完成了一個SQL模組。那如果我們要完成一個自定義的.map函式呢?可類似下面的實現:
abstract class MapCompositor[T,U] extends Compositor[T]{ private var _configParams: util.List[util.Map[Any, Any]] = _ val logger = Logger.getLogger(classOf[SQLCompositor[T]].getName) override def initialize(typeFilters: util.List[String], configParams: util.List[util.Map[Any, Any]]): Unit = { this._configParams = configParams } override def result(alg: util.List[Processor[T]], ref: util.List[Strategy[T]], middleResult: util.List[T], params: util.Map[Any, Any]): util.List[T] = { val dstream = middleResult(0).asInstanceOf[DStream[String]] val newDstream = dstream.map(f=>parseLog(f)) List(newDstream.asInstanceOf[T]) } def parseLog(line:String): U }class YourCompositor[T,U] extends MapCompositor[T,U]{ override def parseLog(line:String):U={ ....your logical } }
同理你可以實現filter,repartition等其他函式。
總結
該方式提供了一套更為高層的API抽象,使用者只要關注具體實現而無需關注Spark的使用。同時也提供了一套配置化系統,方便構建資料處理流程,並且複用原有的模組,支援使用SQL進行資料處理。
作者:祝威廉
連結:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/4687/viewspace-2819304/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- Spark Streaming 效能優化Spark優化
- Spark 以及 spark streaming 核心原理及實踐Spark
- Spark 系列(十四)—— Spark Streaming 基本操作Spark
- Spark 系列(十五)—— Spark Streaming 整合 FlumeSpark
- spark學習筆記-- Spark StreamingSpark筆記
- spark2.2.0 配置spark sql 操作hiveSparkSQLHive
- Spark學習筆記(三)-Spark StreamingSpark筆記
- Spark學習進度11-Spark Streaming&Structured StreamingSparkStruct
- Spark Streaming Backpressure分析Spark
- Spark Streaming入門Spark
- Spark Streaming(六):快取與持久化Spark快取持久化
- Spark Streaming——Spark第一代實時計算引擎Spark
- spark基礎之spark streaming的checkpoint機制Spark
- Spark Streaming監聽HDFS檔案(Spark-shell)Spark
- 實戰|使用Spark Streaming寫入HudiSpark
- Spark Streaming學習——DStreamSpark
- Spark Streaming VS FlinkSpark
- Spark Streaming 流式處理Spark
- spark-streaming之 socketTextStreamSpark
- Spark Streaming :基本工作原理Spark
- Spark Streaming 入門指南Spark
- Spark系列 - (3) Spark SQLSparkSQL
- Spark Streaming Failed to read checSparkAI
- Spark Structured Streaming 解析 JSONSparkStructJSON
- Cris 的 Spark Streaming 筆記Spark筆記
- Spark Streaming中的Window操作Spark
- Spark Streaming之dataset例項Spark
- Storm與Spark Streaming比較ORMSpark
- spark sql 實踐(續)SparkSQL
- Spark SQLSparkSQL
- Spark Shuffle實現Spark
- Spark Streaming調優引數及最佳實踐深入剖析-Spark商業調優實戰Spark
- Spark SQL:4.對Spark SQL的理解SparkSQL
- Spark Streaming 的容錯機制Spark
- Spark-Streaming的學習使用Spark
- Spark Streaming的PIDRateEstimator與backpressureSpark
- spark structed streaming 寫入hudi表SparkStruct
- Spark Streaming基礎概念介紹Spark