定義及工作原理
Spark Streaming定義,官網(wǎng)翻譯如下
Spark Streaming是核心Spark API的擴展,可實現(xiàn)實時數(shù)據(jù)流的可擴展,高吞吐量,容錯流處理。
數(shù)據(jù)可以從許多來源(如Kafka,F(xiàn)lume,Kinesis或TCP套接字)中獲取,并且可以使用以高級函數(shù)(如map,reduce,join和window)表示的復(fù)雜算法進行處理。
最后,處理后的數(shù)據(jù)可以推送到文件系統(tǒng),數(shù)據(jù)庫和實時儀表板。 實際上,您可以在數(shù)據(jù)流上應(yīng)用Spark的機器學(xué)習(xí)和圖形處理算法。
工作原理,官網(wǎng)翻譯如下
在內(nèi)部,它的工作原理如下:
Spark Streaming接收實時輸入數(shù)據(jù)流并將數(shù)據(jù)分成批處理,然后由Spark引擎處理以批量生成最終結(jié)果流。
小結(jié)
Spark流數(shù)據(jù)處理就是將實時數(shù)據(jù)輸入,按時間間隔分批次處理(形成一系列RDD)然后按需求輸出。
流數(shù)據(jù)加載之初始化
Python
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")
sc.setLogLevel("WARN")
ssc = StreamingContext(sc, 5)
Scala
import org.apache.spark._
import org.apache.spark.streaming._
// Create a local StreamingContext with two working thread and batch interval of 1 second.
// The master requires 2 cores to prevent a starvation scenario.
val conf = new SparkConf().setMaster("local[2]").setAppName("NetworkWordCount")
val sc = new SparkContext(conf)
sc.setLogLevel("WARN")
val ssc = new StreamingContext(conf, Seconds(5))
小結(jié)
Spark Streaming初始化必須創(chuàng)建一個SparkContext流上下文對象,這是所有流處理的入口,接著創(chuàng)建StreamingContext對象。
如果后面結(jié)構(gòu)化RDD,也就是DataFrame流操作,必須使用StreamingContext正在使用的 SparkContext 創(chuàng)建SparkSession
流數(shù)據(jù)加載之離散化流
Discretized Stream離散化流
Discretized Stream或DStream是Spark Streaming提供的基本抽象。
它表示連續(xù)的數(shù)據(jù)流,可以是從源接收的輸入數(shù)據(jù)流,也可以是通過轉(zhuǎn)換輸入流生成的已處理數(shù)據(jù)流。 在內(nèi)部,DStream由一系列連續(xù)的RDD表示,這是Spark對不可變分布式數(shù)據(jù)集的抽象。
DStream中的每個RDD都包含來自特定時間間隔的數(shù)據(jù)。
其實,DStram很好理解,就是按時間間隔組合的一系列RDD,其特點就是離散且持續(xù)。
離散流DStream的輸入
Spark Streaming提供兩類內(nèi)置流媒體源。
基本來源:StreamingContext API中直接提供的源。 示例:文件系統(tǒng)和套接字連接。如上面StreamingContext。
高級資源:Kafka,F(xiàn)lume,Kinesis等資源可通過額外的實用程序類獲得。 這些需要鏈接額外的依賴關(guān)系,如鏈接部分所述。
離散流DStream的轉(zhuǎn)化
與RDD類似,轉(zhuǎn)換允許修改來自輸入DStream的數(shù)據(jù)。 DStreams支持普通Spark RDD上可用的許多轉(zhuǎn)換。
DStream同樣與RDD一樣有map、flatmap、union、reduce、transform等等,但是區(qū)別于RDD,這些transform算子都不同于RDD算子的封裝操作(針對于一些了RDD的操作),但其底層還是對每個RDD的操作。
離散流DStream的輸出
輸出操作允許將DStream的數(shù)據(jù)推送到外部系統(tǒng),如數(shù)據(jù)庫或文件系統(tǒng)。
由于輸出操作實際上允許外部系統(tǒng)使用轉(zhuǎn)換后的數(shù)據(jù),因此它們會觸發(fā)所有DStream轉(zhuǎn)換的實際執(zhí)行(類似于RDD的操作)
print(在Python API中pprint)、saveAsTextFiles、foreachRDD等等輸出。
其中,值得注意的是,無論是什么輸出底層調(diào)用的都是foreachRDD函數(shù)。
流數(shù)據(jù)處理擴展
了解更多,請參考 官網(wǎng)后續(xù)包括,結(jié)構(gòu)化RDD的流操作、檢查點、部署等等。
DataFrame流處理操作Demo
r"""
Use DataFrames and SQL to count words in UTF8 encoded, '\n' delimited text received from the
network every second.
Usage: sql_network_wordcount.py <hostname> <port>
<hostname> and <port> describe the TCP server that Spark Streaming would connect to receive data.
To run this on your local machine, you need to first run a Netcat server
`$ nc -lk 9999`
and then run the example
`$ bin/spark-submit examples/src/main/python/streaming/sql_network_wordcount.py localhost 9999`
"""
from __future__ import print_function
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
from pyspark.sql import Row, SparkSession
def getSparkSessionInstance(sparkConf):
# if ('sparkSessionSingletonInstance' not in globals()):
# 創(chuàng)建SparkSession
# 必須使用StreamingContext正在使用的SparkContext創(chuàng)建SparkSession
globals()['sparkSessionSingletonInstance'] = SparkSession \
.builder \
.config(conf=sparkConf) \
.getOrCreate()
return globals()['sparkSessionSingletonInstance']
def process(time, rdd):
# Convert RDDs of the words DStream to DataFrame and run SQL query
print("========= %s =========" % str(time))
try:
# Get the singleton instance of SparkSession
spark = getSparkSessionInstance(rdd.context.getConf())
# Convert RDD[String] to RDD[Row] to DataFrame
rowRdd = rdd.map(lambda w: Row(word=w))
wordsDataFrame = spark.createDataFrame(rowRdd)
# Creates a temporary view using the DataFrame.
wordsDataFrame.createOrReplaceTempView("words")
# Do word count on table using SQL and print it
wordCountsDataFrame = \
spark.sql("select word, count(*) as total from words group by word")
wordCountsDataFrame.show()
except:
pass
if __name__ == "__main__":
# SparkContext---StreamingContext---SparkSession
host, port = ["localhost", 9999]
sc = SparkContext(appName="PythonSqlNetworkWordCount")
# 默認log應(yīng)該是info級,信息較多不利于觀察;
sc.setLogLevel("WARN")
ssc = StreamingContext(sc, 5)
# Create a socket stream on target ip:port and count the
# words in input stream of \n delimited text (eg. generated by 'nc')
lines = ssc.socketTextStream(host, int(port))
words = lines.flatMap(lambda line: line.split(" "))
words.foreachRDD(process)
# 標準用法,沒有output(foreachRDD)都是懶加載,只會記錄后刪除,并不運行;
ssc.start()
ssc.awaitTermination()