spark官方文檔之——Spark Streaming Programming Guid spark streaming編程指南


概述

spark streaming是core spark api的擴展,能夠進行可伸縮的、高通量、容錯的實時流處理。數據可來源於kafka,flume,twitter,zeromq,kinesis或tcp sockets,基於這些數據的複雜算法可用高層次函數,像map,reduce,join和window進行處理。最後,處理過的數據可被存儲到文件系統,數據庫和實時儀表盤上。實際上,你可以在數據流上進行spark的machine learning和graph processing。

它如下圖工作。spark streaming接收到實時輸入數據流,並把數據分批次,這些數據會被spark引擎分批次處理得到最後的結果。


spark streaming提供了一個高層次的抽象概念,稱爲分佈式流或DStream,它代表一個源源不斷的數據流。DStreams可以從像kafka,flume和kinesis的數據源創建得到,也可以在其他DStreams進行操作得到。DStream內部是一系列RDDs。

本指南向你展示了怎樣用DStream來編寫spark streaming程序。你可以用scala,java或python(spark 1.2引入)寫spark streaming程序。(官方所有語言都有,但這裏只翻譯java版本)

一個例子

在怎樣寫你自己的spark streaming程序之前,讓我們先看一下簡單的spark streaming程序都長啥樣。我們要計算監聽一個tcp socket得到的文本數據的單詞數,如下進行:

java:

首先,我們創建JavaStreamingContext對象,它是所有流處理函數的主要入口點。我們創建一個本地StreamingContext,兩個線程運行,並間隔1s一個處理批次(接受1s的數據處理一次)。
import org.apache.spark.*;
import org.apache.spark.api.java.function.*;
import org.apache.spark.streaming.*;
import org.apache.spark.streaming.api.java.*;
import scala.Tuple2;

// Create a local StreamingContext with two working thread and batch interval of 1 second
SparkConf conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCount")
JavaStreamingContext jssc = new JavaStreamingContext(conf, Durations.seconds(1))
使用這個context,我們可以創建一個數據流DStream,它來自於tcp source,並指定了主機名(例如localhost)和端口(例如9999)。
// Create a DStream that will connect to hostname:port, like localhost:9999
JavaReceiverInputDStream<String> lines = jssc.socketTextStream("localhost", 9999);
lines代表接收自數據服務器的數據流。這個流中的每個記錄是一個文本行。然後,我們想把這行文本分離成單詞。
// Split each line into words
JavaDStream<String> words = lines.flatMap(
  new FlatMapFunction<String, String>() {
    @Override public Iterable<String> call(String x) {
      return Arrays.asList(x.split(" "));
    }
  });
flatMap是創建一個新的DStream的DStream操作,它從源DStream的每個記錄生成多個新的記錄。在這種情況下,每行會被分成多個單詞,由words表示。注意我們用FlatMapFunction對象定義了此轉換過程。java api中還有很多這種類來幫助定義DStream transformtions。
接下來,我們想要計算單詞數。
// Count each word in each batch
JavaPairDStream<String, Integer> pairs = words.mapToPair(
  new PairFunction<String, String, Integer>() {
    @Override public Tuple2<String, Integer> call(String s) {
      return new Tuple2<String, Integer>(s, 1);
    }
  });
JavaPairDStream<String, Integer> wordCounts = pairs.reduceByKey(
  new Function2<Integer, Integer, Integer>() {
    @Override public Integer call(Integer i1, Integer i2) {
      return i1 + i2;
    }
  });

// Print the first ten elements of each RDD generated in this DStream to the console
wordCounts.print();
words通過使用PairFunction對象,被映射(one-to-one的轉換)爲(word,1)鍵值對DStream。然後,使用Function2對象計算每個數據批次的單詞數。最後,wordCounts.print()會每秒打印一些單詞數。
注意,spark streaming start之後這些代碼行才執行。爲了所有被建立的轉換被執行,我們最後要調用start方法。

jssc.start();              // Start the computation
jssc.awaitTermination();   // Wait for the computation to terminate
完整的代碼可在https://github.com/apache/spark/blob/master/examples/src/main/java/org/apache/spark/examples/streaming/JavaNetworkWordCount.java找到。
如果你已經下載並搭建了spark,你可以如下運行例程。你要首先運行Netcat(多數unix-like系統中有的小工具)作爲數據服務器:
$ nc -lk 9999
然後,另一個終端中,如下開始例程:
$ ./bin/run-example streaming.JavaNetworkWordCount localhost 9999
然後,運行netcat服務的終端輸入的行都會每秒被計算一次並打印在屏幕上,如下:


基本概念

接下來,詳細討論spark streaming的基礎。

Linking

寫spark streaming程序時,你要添加如下依賴庫到你的SBT或Maven工程。

maven:
<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-streaming_2.10</artifactId>
    <version>1.4.0</version>
</dependency>
sbt:
libraryDependencies += "org.apache.spark" % "spark-streaming_2.10" % "1.4.0"
若想使用來源於像kafka,flume,kinesis這些不存在於spark streaming api中的數據,你需要增加一些依賴庫,例如如下一些:
Source Artifact
Kafka spark-streaming-kafka_2.10
Flume spark-streaming-flume_2.10
Kinesis spark-streaming-kinesis-asl_2.10 [Amazon Software License]
Twitter spark-streaming-twitter_2.10
ZeroMQ spark-streaming-zeromq_2.10
MQTT spark-streaming-mqtt_2.10

初始化StreamingContext

初始化一個spark streaming程序,必須創建StreamingContext對象,它是所有spark streaming函數功能的主要入口點。
java:
JavaStreamingContext對象能夠從一個SparkConf對象創建而來。
import org.apache.spark.*;
import org.apache.spark.streaming.api.java.*;

SparkConf conf = new SparkConf().setAppName(appName).setMaster(master);
JavaStreamingContext ssc = new JavaStreamingContext(conf, Duration(1000));
appName是顯示在集羣UI上的程序名。master是一個spark,mesos或yarn集羣URL,或“local[n]”字符串(運行在本地模式)。實際上,當在一個集羣上運行時,你不會想要把master硬編碼到程序中,而是spark-submit指定。但是,對於本地測試和單元測試,你可以通過“local[n]”在一個進程中運行spark streaming(多個線程模擬集羣)。注意,ssc.sparkContext可訪問JavaSparkContext(所有spark功能函數的入口點)。
batch間隔要根據你的應用的延遲需要和可獲得的集羣資源來設置。更多請參考performance tuning章節。
JavaStreamingContext可從一個存在的JavaSparkContext對象創建。
import org.apache.spark.streaming.api.java.*;

JavaSparkContext sc = ...   //existing JavaSparkContext
JavaStreamingContext ssc = new JavaStreamingContext(sc, Durations.seconds(1));
在context創建之後,你要如下進行:
1.通過創建輸入DStreams定義輸入數據源。
2.
未完待續········

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