- Part 1 綜述

原文地址:http://spark.apache.org/docs/latest/streaming-programming-guide.html

綜述:

Spark Streaming是基於Spark核心包的擴展,它具備可擴容(可以增加節點),高通量(處理數據量大)和可容錯(能夠在節點失敗時重啓恢復)的特性對數據流進行處理。數據流可以從很多數據源獲得,例如Kafka, Flume, Kinesis, 或者簡單的TCP socket,我們可以使用基本的變換函數如map, reduce,join和window構建任意複雜的算法來處理流數據,從而實現我們想要的邏輯。最終,處理後的數據可以持久化到文件系統,數據庫或者直接顯示在動態儀表盤上。另外,如同RDD上一樣,可以在數據流上很容易應用Spark的機器學習圖處理方法。
Spark Streaming

在Spark內部,Spark Streaming將接收到的數據流切分成一個個小的批處理,然後再由Spark 引擎批量生成結果的數據流。
Spark Streaming

Spark Streaming引入了一個高度抽象的概念discretized stream (DStream),離散數據流, 用來代表客觀世界持續不斷的數據流。DStream可以通過之前提過的數據源如Kafka, Flume, and Kinesis獲得,亦可以通過其他的DStream變換而來。在內部,DStream就是一組RDD序列(多個RDD組成的序列),對DStream的操作實際上對一組RDD的操作。既然RDD transform之後還是RDD,所以DStream transform之後還是DStream.


簡單例子
在扎進具體的細節之前,我們先看一個簡單例子大概瞭解Spark Streaming的程序到底長什麼樣子。假設我們在監聽一個TCP Socket,它源源不斷的發給我們一行行的句子,每一行句子由若干個空格分隔的單詞。我們想統計一下過去某一個時間段內接收到所有單詞及其頻數。示例代碼以Python爲例,其他語言Java和Scala樣例代碼,請參照原文。


首先我們需要導入StreamingContext,它是Spark Streaming功能的入口,在下面的程序中我們直接和間接地指定了這個Spark程序有2個執行的線程,批處理的週期是1秒,它意味着我們統計的是過去1秒鐘的接收到的數據。

from pyspark import SparkContext
from pyspark.streaming import StreamingContext

# Create a local StreamingContext with two working thread and batch interval of 1 second
sc = SparkContext("local[2]", "NetworkWordCount")
ssc = StreamingContext(sc, 1)


通過這個StreamingContext,我們能夠創建一個DStream代表從Socket 監聽到的數據流,Socket 地址通過主機名和端口指定,在我們的例子中指定的是本機的9999端口。

# Create a DStream that will connect to hostname:port, like localhost:9999
lines = ssc.socketTextStream("localhost", 9999)

DStream變量lines由一組RDD組成,每一個RDD是過去1秒鐘內監聽的所有數據,儘管是1秒,一個RDD數據仍然可能包含不止一行的句子,每一行句子由若干個由空格分隔的單詞組成。接下來我們將DStream進行flatMap操作,實際上是對每一個RDD的flatMap的操作,flatMap的操作是首先將每一行的句子按照空格提取爲一個個單詞構成的數組,然後再將數組打扁(flatten),從而構成由多個小數組連接爲成一個只有一層的大數組。這個從單個RDD的視角去看,包含多行句子RDD轉換成了單詞的RDD,如果從DStream,即一組RDD的視角看,結果集words依然是一組RDD的集合,即還是一個DStream。

# Split each line into words
words = lines.flatMap(lambda line: line.split(" "))

繼續進行,對DStream 'word' 進行map操作,即對每一個包含其中的RDD進行map操作,操作的內容是將每一個單詞轉換成key-value的pair RDD,key是單詞,value是常數1. 結果集依然是一組RDD,即依然是DStream。然後進行reduceByKey操作,從而將相同key的value進行加和,從而求得每一個單詞出現的個數。最後通過pprint()函數打印前10條記錄。

譯者的話:其實我認爲更實際的應用場景中,與其給出任意十個單詞出現的頻數,不如將結果按照頻數進行降序排序,然後列出出現頻度最高的N的單詞及其具體的頻數。


# Count each word in each batch
pairs = words.map(lambda word: (word, 1))
wordCounts = pairs.reduceByKey(lambda x, y: x + y)

# Print the first ten elements of each RDD generated in this DStream to the console
wordCounts.pprint()

注意到目前爲止,我們只是定義了計算方式,還實際上啓動任何實際的流處理。當所有的計算方式定義結束後,我們可以執行下面的代碼從而啓動流處理程序。

ssc.start()             # Start the computation
ssc.awaitTermination()  # Wait for the computation to terminate


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