Spark Streaming 入門指南
本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃!
這篇部落格幫你開始使用Apache Spark Streaming和HBase。Spark Streaming是核心Spark API的一個擴充套件,它能夠處理連續資料流。
Spark Streaming是什麼?
首先,Spark Streaming是什麼?資料流是資料連續到來的無限序列。Streaming劃分連續流動的輸入資料成離散單元以便處理。流處理是對流資料的低延遲處理和分析。Spark Streaming是核心Spark API的一個擴充套件,能夠允許對實時資料的可擴充套件,高吞吐量,容錯流處理。Spark Streaming用於需要快速處理實時到來的大資料量的應用情形。
實時應用情形的例項有以下場合:
- 網路站點監控,網路監控
- 欺詐偵測
- 網路點選
- 廣告
- 物聯網感測器
Spark Streaming支援的資料來源有:HDFS directories, TCP sockets, Kafka, Flume, Twitter等等。Data Streams能被Spark的核心APIS,DataFrames SQL,或機器學習APIs,來處理,還能夠持久化到檔案系統,HDFS,資料庫,或任何提供Hadoop OutputFormat的資料來源。
Spark Streaming是怎麼執行的
Spark Streaming劃分一個資料流成X秒一組的資料,它被稱為Dstreams,本質上是RDDs的一個序列。你的Spark應用程式使用Spark APIs處理RDDs,RDD操作的處理結果成批地返回。
一個Streaming應用例項的架構
Spark Streaming例項程式碼完成了以下操作:
- 讀流資料
- 處理流資料
- 將處理過的資料寫入到HBase Table
另外的Spark例項程式碼會執行下面操作:
- 讀取由streaming程式碼寫入的HBase Table資料
- 計算每日的彙總統計結果
- 將統計結果寫入到HBase Table Column Family stats(HBase Table統計列族)
樣本資料集
油量泵感測器資料來自於目錄中一個逗號分隔值(csv)檔案。Spark Streaming監控那個目錄,並處理目錄中建立的任何檔案。(正如之前提到的,Spark Streaming支援不同的流資料來源;為了簡單化,這個例子使用了檔案。)下面是csv檔案樣本資料的一個例子:
我們使用Scala 樣本類(case class)定義對應於感測器資料csv檔案的感測器資料庫模式,使用一個parseSensor函式去解析在感測器樣本類(case class)中的逗號分隔值。
HBase Table Schema
流資料的HBase Table Schema如下:
- 泵名稱日期和時間戳的複合行鍵。
- 列中的Column Family資料對應於輸入資料域,Column Family告警列對應於警報值篩選器。注意,經過一定時間後,資料和告警列集會被設定成終止值。
日常統計資料彙總歸納的Schema列舉如下:
- 泵名稱和日期的複合行鍵。
- 統計列族(Column Family stats)
- 最小列,最大列,平均列
下面的函式轉換一個Sensor 物件成為一個HBase Put物件,用於往HBase插入一行。
寫入一個HBase Table的配置
你可以使用Spark中的TableOutputFormat 類來寫一個HBase Table,類似於你怎樣從MapReduce 往HBase Table中寫資料。下面我們使用TableOutputFormat類來設定要往HBase中寫的配置。
Spark Streaming例子程式碼
這些是Spark Streaming程式碼的基本步驟:
1.初始化一個Spark StreamingContext物件;
2.對DStreams應用轉換和輸出操作;
3.使用streamingContext.start()來開始接收資料和處理;
4.使用streamingContext.awaitTermination()來等待處理過程停止;
我們會使用實際的應用程式程式碼完成上面的每一步。
初始化StreamingContext
首先,我們建立一個StreamingContext,它是流功能函式主入口點,是有一個兩秒批間隔。
val sparkConf = new SparkConf().setAppName("HBaseStream") // create a StreamingContext, the main entry point for all streaming functionality val ssc = new StreamingContext(sparkConf, Seconds(2))
下一步,我們使用StreamingContext textFileStream(目錄) 方法建立輸入流,它用於監控Hadoop-相容(Hadoop-compatible)的檔案系統,檔案系統用於新檔案,輸入流也處理在這個目錄下任何檔案建立的操作。
// create a DStream that represents streaming data from a directory source val linesDStream = ssc.textFileStream("/user/user01/stream")
那個linesDStream代表資料流,每條記錄是文字中的一行。本質上,DStream 是RDDs的一個序列,代表每批次間隔的一個RDD。
對DStreams應用轉換和輸出操作
接著,我們解析資料行成Sensor物件,對linesDStream使用對映操作.
// parse each line of data in linesDStream into sensor objects val sensorDStream = linesDStream.map(Sensor.parseSensor)
對映操作使用Sensor.parseSensor函式對linesDStream中的RDDs進行操作,獲得了RDDs of Sensor物件。
接下來,我們使用DStream的 foreachRDD方法去對這個DStream中的每個RDD進行處理。我們篩選那個感測器物件到適合的低壓力值去建立告警,通過轉換它們成Put物件來將感測器和告警資料寫入到HBase中,接著使用PairRDDFunctions 的saveAsHadoopDataset方法,輸出RDD到支援Hadoop的任何儲存系統,那個儲存系統使用一個Hadoop Configuration物件(檢視上面的HBase的Hadoop Configuration)。
// for each RDD. performs function on each RDD in DStream sensorRDD.foreachRDD { rdd => // filter sensor data for low psi val alertRDD = rdd.filter(sensor => sensor.psi < 5.0) // convert sensor data to put object and write to HBase Table CF data rdd.map(Sensor.convertToPut).saveAsHadoopDataset(jobConfig) // convert alert to put object write to HBase Table CF alerts rdd.map(Sensor.convertToPutAlert).saveAsHadoopDataset(jobConfig) }
那個感測器RDD物件被轉換成Put物件,然後寫入HBase。
開始接收資料
為了開始接收資料,我們必須在StreamingContext中顯式地呼叫start(),然後呼叫awaitTermination去等待流計算直到它終止。
// Start the computation ssc.start() // Wait for the computation to terminate ssc.awaitTermination()
從Spark中讀取和寫回HBase
現在我們想要讀取HBase感測器表資料,計算每日彙總統計資料,將統計資料寫到統計列族。
下面的程式碼讀取HBase感測器表壓力列資料,使用StatCounter計算這個資料的統計值,將統計資料寫入到感測器統計列族。
// configure HBase for reading val conf = HBaseConfiguration.create() conf.set(TableInputFormat.INPUT_TABLE, HBaseSensorStream.tableName) // scan data column family psi column conf.set(TableInputFormat.SCAN_COLUMNS, "data:psi") // Load an RDD of (row key, row Result) tuples from the table val hBaseRDD = sc.newAPIHadoopRDD(conf, classOf[TableInputFormat], classOf[org.apache.hadoop.hbase.io.ImmutableBytesWritable], classOf[org.apache.hadoop.hbase.client.Result]) // transform (row key, row Result) tuples into an RDD of Results val resultRDD = hBaseRDD.map(tuple => tuple._2) // transform into an RDD of (RowKey, ColumnValue)s , with Time removed from row key val keyValueRDD = resultRDD. map(result => (Bytes.toString(result.getRow()). split(" ")(0), Bytes.toDouble(result.value))) // group by rowkey , get statistics for column value val keyStatsRDD = keyValueRDD. groupByKey(). mapValues(list => StatCounter(list)) // convert rowkey, stats to put and write to hbase table stats column family keyStatsRDD.map { case (k, v) => convertToPut(k, v) }.saveAsHadoopDataset(jobConfig)
下面這個圖顯示了newAPIHadoopRDD的輸出是一個RDD行鍵值,成對出現。那個PairRDDFunctions的 saveAsHadoopDataset方法儲存Put物件到HBase中。
軟體
這個示例執行在MapR Sandbox上,包含了Spark。
你可以從下面網址下載程式碼和資料來執行這個例子:https://github.com/caroljmcdonald/SparkStreamingHBaseExample
執行程式
你可以執行那些程式碼作為一個獨立應用程式,正如Getting Started with Spark on MapR Sandbox示例中所描述的。
這裡是步驟總結:
- 使用使用者名稱user01,密碼mapr登入MapR Sandbox, 正如Getting Started with Spark on MapR Sandbox所描述的。
- 使用Maven編譯應用程式。
- 使用scp命令拷貝jar檔案和資料檔案到你的sandbox根目錄/user/user01。
- 執行流app:
/opt/mapr/spark/spark-<version>/bin/spark-submit --driver-class-path `hbase classpath` --class examples.HBaseSensorStream sparkstreamhbaseapp-1.0.jar
- 拷貝流資料檔案到流目錄:
cp sensordata.csv /user/user01/stream/
- 讀資料計算一列的統計資料:
/opt/mapr/spark/spark-<version>/bin/spark-submit --driver-class-path `hbase classpath` --class examples.HBaseReadWrite sparkstreamhbaseapp-1.0.jar
- 計算整行的統計資料:
/opt/mapr/spark/spark-<version>/bin/spark-submit --driver-class-path `hbase classpath` --class examples.HBaseReadRowWriteStats sparkstreamhbaseapp-1.0.jar
結語
關於Spark Streaming with HBase的示例敘述就結束了。在以下參考部分,你可以找到更多資訊。
Getting Started with Apache Spark: From Inception to Production Book
Apache Spark Streaming Programming guide
譯文連結:http://www.codeceo.com/article/spark-streaming-guide.html
英文原文:Getting Started With Spark Streaming
翻譯作者:碼農網 – 小峰
[ 轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]
相關文章
- Spark Streaming入門Spark
- Spark Streaming簡單入門(示例+原理)Spark
- Spark Streaming和Kafka整合開發指南(一)SparkKafka
- Spark Streaming和Kafka整合開發指南(二)SparkKafka
- spark structed streaming 寫入hudi表SparkStruct
- 實戰|使用Spark Streaming寫入HudiSpark
- 教程:Apache Spark SQL入門及實踐指南!ApacheSparkSQL
- Spark學習進度11-Spark Streaming&Structured StreamingSparkStruct
- Spark 系列(十四)—— Spark Streaming 基本操作Spark
- Spark 系列(十五)—— Spark Streaming 整合 FlumeSpark
- spark學習筆記-- Spark StreamingSpark筆記
- Spark Streaming Backpressure分析Spark
- Spark學習筆記(三)-Spark StreamingSpark筆記
- Spark 快速入門Spark
- Spark入門篇Spark
- Spark Streaming學習——DStreamSpark
- Spark Streaming VS FlinkSpark
- Spark Streaming 流式處理Spark
- spark-streaming之 socketTextStreamSpark
- Spark Streaming :基本工作原理Spark
- Spark Streaming 效能優化Spark優化
- Spark Streaming + Spark SQL 實現配置化ETSparkSQL
- Spark 以及 spark streaming 核心原理及實踐Spark
- Hello Spark! | Spark,從入門到精通Spark
- Spark SQL | Spark,從入門到精通SparkSQL
- spark入門筆記Spark筆記
- Spark入門學習Spark
- 01_spark入門Spark
- 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基礎之spark streaming的checkpoint機制Spark
- Spark Streaming監聽HDFS檔案(Spark-shell)Spark
- Spark下載與入門(Spark自學二)Spark
- Spark Streaming 的容錯機制Spark