小結-Spark-Spark Streaming入門

定義及工作原理

Spark Streaming定義,官網翻譯如下

Spark Streaming是核心Spark API的擴展,可實現實時數據流的可擴展,高吞吐量,容錯流處理。

數據可以從許多來源(如Kafka,Flume,Kinesis或TCP套接字)中獲取,并且可以使用以高級函數(如map,reduce,join和window)表示的復雜算法進行處理。

最后,處理后的數據可以推送到文件系統,數據庫和實時儀表板。 實際上,您可以在數據流上應用Spark的機器學習和圖形處理算法。

工作原理,官網翻譯如下

在內部,它的工作原理如下:

Spark Streaming接收實時輸入數據流并將數據分成批處理,然后由Spark引擎處理以批量生成最終結果流。

小結

Spark流數據處理就是將實時數據輸入,按時間間隔分批次處理(形成一系列RDD)然后按需求輸出。

流數據加載之初始化

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))

小結

Spark Streaming初始化必須創建一個SparkContext流上下文對象,這是所有流處理的入口,接著創建StreamingContext對象。

如果后面結構化RDD,也就是DataFrame流操作,必須使用StreamingContext正在使用的 SparkContext 創建SparkSession

流數據加載之離散化流

Discretized Stream離散化流

Discretized Stream或DStream是Spark Streaming提供的基本抽象。

它表示連續的數據流,可以是從源接收的輸入數據流,也可以是通過轉換輸入流生成的已處理數據流。 在內部,DStream由一系列連續的RDD表示,這是Spark對不可變分布式數據集的抽象。

DStream中的每個RDD都包含來自特定時間間隔的數據。

其實,DStram很好理解,就是按時間間隔組合的一系列RDD,其特點就是離散且持續。

離散流DStream的輸入

Spark Streaming提供兩類內置流媒體源。

基本來源:StreamingContext API中直接提供的源。 示例:文件系統和套接字連接。如上面StreamingContext。

高級資源:Kafka,Flume,Kinesis等資源可通過額外的實用程序類獲得。 這些需要鏈接額外的依賴關系,如鏈接部分所述。

離散流DStream的轉化

與RDD類似,轉換允許修改來自輸入DStream的數據。 DStreams支持普通Spark RDD上可用的許多轉換。

DStream同樣與RDD一樣有map、flatmap、union、reduce、transform等等,但是區別于RDD,這些transform算子都不同于RDD算子的封裝操作(針對于一些了RDD的操作),但其底層還是對每個RDD的操作。

離散流DStream的輸出

輸出操作允許將DStream的數據推送到外部系統,如數據庫或文件系統。

由于輸出操作實際上允許外部系統使用轉換后的數據,因此它們會觸發所有DStream轉換的實際執行(類似于RDD的操作)

print(在Python API中pprint)、saveAsTextFiles、foreachRDD等等輸出。

其中,值得注意的是,無論是什么輸出底層調用的都是foreachRDD函數。

流數據處理擴展

了解更多,請參考 官網后續包括,結構化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()):
    # 創建SparkSession
    # 必須使用StreamingContext正在使用的SparkContext創建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應該是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()

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容