Spark Streaming 入門指南

2016-04-23    分類:作業系統、程式設計開發、首頁精華0人評論發表於2016-04-23

本文由碼農網 – 小峰原創翻譯,轉載請看清文末的轉載要求,歡迎參與我們的付費投稿計劃

這篇部落格幫你開始使用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

Learning Spark O’Reilly Book

Databricks Spark Streaming

譯文連結:http://www.codeceo.com/article/spark-streaming-guide.html
英文原文:Getting Started With Spark Streaming
翻譯作者:碼農網 – 小峰
轉載必須在正文中標註並保留原文連結、譯文連結和譯者等資訊。]

相關文章