pyspark系列7-Spark streaming介紹 一.Spark streaming介紹 二.Spark Streaming的組件介紹 三.一個簡單的測試用例 參考:

一.Spark streaming介紹

1.1 Spark streaming簡介

Spark Streaming是Spark API的核心擴展,支持實時數據流的可擴展、高吞吐量和容錯流處理。數據可以從Kafka、Kinesis或TCP套接字等多種來源中獲取,並且可以使用複雜的算法進行處理,這些算法用高級函數表示,如map、reduce、join和window。最後,處理過的數據可以推送到文件系統、數據庫和實時儀表板。事實上,您可以在數據流上應用Spark的機器學習和圖形處理算法。


在內部,它的工作方式如下。Spark Streaming接收實時輸入的數據流,並對數據進行分批處理,由Spark引擎進行處理,生成最終的批量結果流。


Spark Streaming提供了一種高級抽象,稱爲離散流或DStream,它表示連續的數據流。Dstream可以通過來自Kafka和Kinesis等源的輸入數據流創建,也可以通過在其他Dstream上應用高級操作來創建。在內部,DStream表示爲rdd序列。

1.2 Spark 與storm區別

Storm

  1. 流式計算框架
  2. 以record爲單位處理數據
  3. 也支持micro-batch方式(Trident)

Spark

  1. 批處理計算框架
  2. 以RDD爲單位處理數據
  3. 也支持micro-batch流式處理數據(Spark Streaming)

兩者異同

  1. 吞吐量: Spark Streaming 優於Storm
  2. 延遲: Spark Streaming差於Storm

1.3 一個簡單的例子

在我們深入瞭解如何編寫自己的Spark Streaming程序之前,讓我們快速瞭解一下簡單的Spark Streaming程序是什麼樣的。

首先,我們導入StreamingContext,它是所有流功能的主要入口點。我們創建一個具有兩個執行線程的本地StreamingContext,批處理間隔爲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)

爲了初始化一個Spark Streaming程序,必須創建一個StreamingContext對象,它是所有Spark Streaming功能的主要入口點。

appName參數是應用程序在集羣UI上顯示的名稱。master是Spark、Mesos或YARN集羣的URL,或者是一個特殊的“local[*]”字符串,在本地模式下運行。實際上,當在集羣上運行時,您不希望在程序中硬編碼master,而是使用spark-submit啓動應用程序並在那裏接收它。但是,對於本地測試和單元測試,可以通過“local[*]”來運行Spark Streaming in-process(檢測本地系統中的核數)。

在定義了上下文之後,必須執行以下操作:

  1. 通過創建輸入DStreams來定義輸入源。
  2. 通過對DStreams應用轉換和輸出操作來定義流計算。
  3. 開始接收數據並使用streamingContext.start()處理它。
  4. 使用streamingContext.awaitTermination()等待處理停止(手動或由於任何錯誤)。
  5. 可以使用streamingContext.stop()手動停止處理。

注意:

  1. 一旦啓動了Context,就不能再設置或向其添加新的流計算。
  2. 一旦停止了Context,就不能重新啓動它。
  3. 同一時間,JVM中只能有一個StreamingContext是活動的。
  4. StreamingContext上的stop()也會停止SparkContext。要只停止StreamingContext,請將stop()的可選參數stopSparkContext設置爲false。
  5. 一個SparkContext可以被重用來創建多個StreamingContext,只要在創建下一個StreamingContext之前停止前一個StreamingContext(不停止SparkContext)。

二.Spark Streaming的組件介紹

Spark Streaming的核心組件有2個:

  1. Streaming Context
  2. Dstream(離散流)

2.1 Streaming Context

Streaming Context是Spark Streaming程序的起點,生成Streaming Context之前需要生成SparkContext,SparkContext可以理解爲申請Spark集羣的計算資源,Streaming Context可以理解爲申請Spark Streaming的計算資源

2.2 Dstream(離散流)

Dstream是Spark Streaming的數據抽象,同DataFrame,其實底層依舊是RDD。

Discretized Stream或DStream是Spark Streaming提供的基本抽象。它表示一個連續的數據流,要麼是從源接收的輸入數據流,要麼是通過轉換輸入流生成的處理數據流。在內部,DStream由一系列連續的rdd表示,這是Spark對不可變的分佈式數據集的抽象。DStream中的每個RDD都包含一定時間間隔的數據,如下圖所示:


在DStream上應用的任何操作都轉換爲在底層rdd上的操作。


這些底層RDD轉換是由Spark引擎計算的。DStream操作隱藏了大部分細節,併爲開發人員提供了更高級的API。

DStream存在如下概念:

  1. Receiver
  2. 數據源: 基本源、高級源
  3. 可靠性
  4. Dstream的操作
  5. 緩存
  6. Checkpoint

2.1 Receiver

每個輸入DStream(文件流除外)都與一個Receiver (Scala doc, Java doc)對象相關聯,接收來自源的數據並將其存儲在Spark的內存中進行處理。

2.2 數據源

Spark Streaming提供了兩類內置流源:

  1. 基本源:在StreamingContext API中直接可用的源。例如文件系統和套接字連接。
  2. 高級資源:像Kafka, Kinesis等資源可以通過額外的實用程序類獲得。這些需要根據鏈接部分中討論的額外依賴項進行鏈接。

注意,如果希望在流應用程序中並行接收多個數據流,可以創建多個輸入Dstream。這將創建多個接收器,這些接收器將同時接收多個數據流。但是請注意,Spark worker/executor是一個長期運行的任務,因此它佔用分配給Spark Streaming應用程序的一個核心。因此,Spark Streaming應用程序需要分配足夠的內核(或者線程,如果在本地運行的話)來處理接收到的數據,以及運行接收端,記住這一點很重要。

記住
在本地運行Spark Streaming程序時,不要使用“local”或“local[1]”作爲主URL。這兩種情況都意味着只有一個線程用於本地運行任務。如果你使用一個基於接收器的輸入DStream(例如,socket, Kafka等),那麼單線程將被用來運行Receiver ,不留下任何線程來處理接收的數據。因此,當本地運行時,總是使用“local[n]”作爲主URL,其中要運行n個>數量的Receiver 。

將邏輯擴展到集羣上,分配給Spark Streaming應用的內核數必須大於接收端數。否則系統將接收到數據,但無法進行處理。

2.3 可靠性

根據數據源的可靠性,可以有兩種數據源。源(如Kafka)允許傳輸的數據被確認。如果從這些可靠來源接收數據的系統正確地確認了接收的數據,就可以確保不會由於任何類型的故障而丟失數據。這就產生了兩種接收者:
1). 可靠的接收端—當數據被接收到並存儲在Spark中並進行復制時,一個可靠的接收端會正確地向一個可靠的源發送確認。
2), 不可靠的接收者——不可靠的接收者不向源發送確認。這可以用於不支持確認的來源,甚至當一個人不想或需要進入確認的複雜性時,用於可靠的來源。

對於不可靠的接收者,Spark streaming有自己的可靠機制,來保證數據的可靠性。

2.4 Dstream的操作

與rdd類似,轉換允許修改來自輸入DStream的數據。DStreams支持許多普通Spark RDD上可用的轉換。下面是一些常見的.

Transformations on DStreams

Output Operations on DStreams:

2.5 緩存

與rdd類似,DStreams也允許開發人員在內存中持久化流數據。也就是說,在DStream上使用persist()方法將自動在內存中持久化該DStream的每個RDD。如果DStream中的數據將被計算多次(例如,對同一數據的多次操作),這是有用的。對於基於窗口的操作,如reduceByWindow和reduceByKeyAndWindow,以及基於狀態的操作,如updateStateByKey,這是隱式true。因此,由基於窗口的操作生成的DStreams會自動持久化到內存中,而不需要開發人員調用persist()。

對於通過網絡接收數據的輸入流(例如,Kafka, socket等),默認的持久性級別被設置爲將數據複製到兩個節點以實現容錯。

注意,與rdd不同,DStreams的默認持久性級別將數據序列化保存在內存中。

2.6 Checkpoint

流應用程序必須全天候運行,因此必須對與應用程序邏輯無關的故障(例如,系統故障、JVM崩潰等)具有彈性。爲了使這成爲可能,Spark Streaming需要對容錯存儲系統進行足夠的信息檢查點,以便從故障中恢復。有兩種類型的數據是檢查點的:

  1. 元數據檢查點——將定義流計算的信息保存到像HDFS這樣的容錯存儲中。這用於從運行流應用程序驅動程序的節點的故障中恢復(稍後將詳細討論)。元數據包括:
    1.1) 配置—用於創建流應用程序的配置。
    1.2) DStream操作-定義流應用程序的DStream操作集。
    1.3) 未完成批-作業已排隊但尚未完成的批。

  2. 數據檢查點——將生成的rdd保存到可靠的存儲中。在一些跨多個批組合數據的有狀態轉換中,這是必要的。在這種轉換中,生成的rdd依賴於以前批次的rdd,這導致依賴鏈的長度隨着時間不斷增加。爲了避免恢復時間的無限增長(與依賴鏈成正比),有狀態轉換的中間rdd會定期被檢查到可靠的存儲(例如HDFS),以切斷依賴鏈。

總之,元數據檢查點主要用於從驅動程序失敗中恢復,而數據或RDD檢查點即使是用於基本功能(如果使用有狀態轉換)也是必要的。

三.一個簡單的測試用例

3.1 linux服務器安裝nc服務

yum -y install netcat.x86_64    -- centos7 正確
yum -y install nc.x86_64          -- centos7 錯誤

nc -lk 9999
[root@hp2 yum.repos.d]# nc -help
usage: nc [-46cDdFhklNnrStUuvz] [-C certfile] [-e name] [-H hash] [-I length]
          [-i interval] [-K keyfile] [-M ttl] [-m minttl] [-O length]
          [-o staplefile] [-P proxy_username] [-p source_port] [-R CAfile]
          [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] [-w timeout]
          [-X proxy_protocol] [-x proxy_address[:port]] [-Z peercertfile]
          [destination] [port]
        Command Summary:
                -4              Use IPv4
                -6              Use IPv6
                -C certfile     Public key file
                -c              Use TLS
                -D              Enable the debug socket option
                -d              Detach from stdin
                -e name         Required name in peer certificate
                -F              Pass socket fd
                -H hash         Hash string of peer certificate
                -h              This help text
                -I length       TCP receive buffer length
                -i interval     Delay interval for lines sent, ports scanned
                -K keyfile      Private key file
                -k              Keep inbound sockets open for multiple connects
                -l              Listen mode, for inbound connects
                -M ttl          Outgoing TTL / Hop Limit
                -m minttl       Minimum incoming TTL / Hop Limit
                -N              Shutdown the network socket after EOF on stdin
                -n              Suppress name/port resolutions
                -O length       TCP send buffer length
                -o staplefile   Staple file
                -P proxyuser    Username for proxy authentication
                -p port         Specify local port for remote connects
                -R CAfile       CA bundle
                -r              Randomize remote ports
                -S              Enable the TCP MD5 signature option
                -s sourceaddr   Local source address
                -T keyword      TOS value or TLS options
                -t              Answer TELNET negotiation
                -U              Use UNIX domain socket
                -u              UDP mode
                -V rtable       Specify alternate routing table
                -v              Verbose
                -W recvlimit    Terminate after receiving a number of packets
                -w timeout      Timeout for connects and final net reads
                -X proto        Proxy protocol: "4", "5" (SOCKS) or "connect"
                -x addr[:port]  Specify proxy address and port
                -Z              Peer certificate file
                -z              Zero-I/O mode [used for scanning]
        Port numbers can be individual or ranges: lo-hi [inclusive]
[root@hp2 yum.repos.d]# 
[root@hp2 yum.repos.d]# 
[root@hp2 yum.repos.d]# 
[root@hp2 yum.repos.d]# nc -lk 9999

3.2 pyspark代碼

代碼:

#!/usr/bin/env python
# encoding: utf-8


"""
@author:  'Administrator'
@contact:
@time:
"""

#!/usr/bin/python
# encoding: utf-8

#
# Streaming Word Count Example
#    Original Source: https://spark.apache.org/docs/1.6.0/streaming-programming-guide.html
#
# To run this example:
# yum install nc.x86_64
#   Terminal 1:  nc -lk 9999
#   Terminal 2:  ./bin/spark-submit streaming_word_count.py
#   Note, type words into Terminal 1
#

# Import the necessary classes and create a local SparkContext and Streaming Contexts
from pyspark import SparkContext
from pyspark.streaming import StreamingContext

if __name__=='__main__':
    # Create Spark Context with two working threads (note, `local[2]`)
    sc = SparkContext("local[2]", "NetworkWordCount")

    # Create local StreamingContextwith batch interval of 1 second
    ssc = StreamingContext(sc, 1)

    # Create DStream that will connect to the stream of input lines from connection to localhost:9999
    # lines is DStream representing the data stream extracted via the ssc.socketTextStream.

    lines = ssc.socketTextStream("localhost", 9999)

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

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

    # Start the computation
    ssc.start()

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

測試記錄:

滾動太快,只能從日誌中找到記錄


參考:

1.http://spark.apache.org/docs/latest/streaming-programming-guide.html

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