概述
Hadoop的MapReduce及Spark SQL等只能進行離線計算,無法滿足實時性要求較高的業務需求,例如實時推薦,實時網站性能分析等,流式計算可以解決這些問題,spark Streaming就是現在常用的流式計算框架。作為spark的五大核心組件之一,spark Streaming原生地支持多種數據源的接入,而且可以與Spark MLLib、Graphx結合起來使用,具有高吞吐量,容錯機制,數據可以從Kafka、flume、Twitter、zeroMQ、K inesis或者TCP的端口,同時能夠被類似于使用map、reduce、join和window這種高級函數的算法所處理,最終,被處理過的數據能夠被推送到磁盤、數據庫。簡而言之,Spark Streaming的作用就是實時的將不同的數據源的數據經過處理之后將結果輸出到外部文件系統。
工作原理
粗粒度
Spark Streaming接收到實時數據流,把數據按照指定的時間段切成一片片小的數據塊,
然后把小的數據塊傳給Spark Engine處理。
細粒度
接收實時輸入數據流,然后將數據拆分成多個batch,比如每收集1秒的數據封裝為一個batch,然后將每個batch交給Spark的計算引擎進行處理,最后會生產出一個結果數據流,其中的數據,也是由一個一個的batch所組成的。
- Spark Streaming提供了一種高級的抽象,叫做DStream,英文全稱為Discretized Stream,中文翻譯為“離散流”,它代表了一個持續不斷的數據流。DStream可以通過輸入數據源來創建,比如Kafka、Flume、ZMQ和Kinesis;也可以通過對其他DStream應用高階函數來創建,比如map、reduce、join、window。
-
DStream的內部,其實一系列持續不斷產生的RDD。RDD是Spark Core的核心抽象,即,不可變的,分布式的數據集。DStream中的每個RDD都包含了一個時間段內的數據。
Spark Streaming基本工作原理 - 對DStream應用的算子,比如map,其實在底層會被翻譯為對DStream中每個RDD的操作。比如對一個DStream執行一個map操作,會產生一個新的DStream。但是,在底層,其實其原理為,對輸入DStream中每個時間段的RDD,都應用一遍map操作,然后生成的新的RDD,即作為新的DStream中的那個時間段的一個RDD。底層的RDD的transformation操作。
-
還是由Spark Core的計算引擎來實現的。Spark Streaming對Spark Core進行了一層封裝,隱藏了細節,然后對開發人員提供了方便易用的高層次的API。
Spark Streaming基本工作原理介紹
實戰
wordcount案例(實時統計)
需求:動態輸入字符,通過Spark Streaming實時計算輸入字符出現的次數。
代碼說明
spark安裝的examples文件中提供了spark streaming的類似案例。在github上可以查看相應的代碼,我們使用的是JavaNetworkWordCount這一案例,在代碼中指名了使用方式。
我們通過以下兩種方式在spark上提交作業。
- spark-submit提交
./spark-submit --master local[2] --class org.apache.spark.examples.streaming.JavaNetworkWordCount --name NetworkWordCount ../examples/jars/spark-examples_2.11-2.1.0.jar localhost 9999
- 測試
nc -lk 9999
若提示nc: command not found 表示沒安裝nc的包,使用以下命令安裝
yum install nc -y
yum install nmap -y
如圖所示可以實時統計出字符出現的次數。
- spark-shell提交
啟動spark-shell
./spark-shell --master local[2]
啟動后執行以下代碼
import org.apache.spark.streaming.{Seconds,StreamingContext};
val ssc = new StreamingContext(sc, Seconds(1));
val lines = ssc.socketTextStream("192.168.30.130", 9999);
val words = lines.flatMap(_.split(" "));
val wordCounts = words.map(x => (x, 1)).reduceByKey(_ + _);
wordCounts.print();
ssc.start();
ssc.awaitTermination();
測試:
如圖所示可以實時統計出字符出現的次數。
兩者的區別:
spark-submit在生產環境使用,spark-shell用于開發時代碼的測試。