spark streaming是Spark核心API的扩展,能够进行可伸缩、高通量、容错实时数据流的流处
理。数据来源多样,例如:Kafka、Flume、Twitter、ZeroMQ、Kinesis或者TCP Sockets。并且
Spark可以使用高级接口(map、reduce、join、window)来实现复杂算法对数据的处理。最终
处理的数据可存放到文件系统、数据库、live dashboards中。实际上,spark streaming还可使
用spark 机器学习、图运算的算法进行数据流处理。
在内容,Spark streaming接收实时输入数据流并将数据拆分为Spark 引擎可处理的批次数据,
然后Spark 引擎产生最终的批次数据处理结果。
Spark Streaming提供了一个称为discretized stream 或DStream的抽象代表连续的数据流。
DStream不仅可以通过Kafka、Flume、Kinesis资淅提供的输入数据流创建,而且可以通
过别的DStream的高级操作产生。DStream本质上是RDDS(弹性数据集)的序列表示。
注意:spark streaming的Python API支持全部的DStream转换操作和几乎全部的JAVA、
SCALA接口支持的输出操作。但是python API仅支持基本的文本文件(text files) 和
建立在Sockets上的文本数据。额外的来源像Kafa、Flume 将出现在Python API的将来版本。
Python API将来可用的特性参考Python API DOC。
在详细介绍如何编写自己的Spark Streaming 程序之前,我们简单看一下Spark streaming 程序
的样例:计算从一台数据服务器上的TCP skocket端口接收的文本数据流中的单词数量。
Python Code:
"""首先引入 StreamingContext,这是所有流处理函数的入口,创建一个拥有2个线程,时间间隔为1秒的本地StreamingContext"""
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)
"""
使用当前Context,我们可创建一个DStream表示来自TCP(主机:localhost,端口9999)
服务的数据流
"""
# Create a DStream that will connect to hostname:port, like
# localhost:9999
lines = ssc.socketTextStream("localhost", 9999)
# Split each line 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()
"""
注意,以上代码执行后,Spark仅是设置这些计算在调用的时候执行,还没有真正的执行计算操作,在所有的转换操作设置完成后,通过以下代码开始实际执行计算操作
"""
ssc.start() # Start the computation
ssc.awaitTermination() # Wait for the computation to terminate
注:完整的代码参考Spark streaming例子:NetworkWordCount
通过以下步骤测试:
在Linux命令行A:$nc –lk 9999
另起一个Linux命令行B,转到Spark根目录下执行:
$ ./bin/spark-submit examples/src/main/python/streaming/
network_wordcount.py
localhost 9999
在Spark启动之后,在Linux命令行A中输入文本,查看Linux命令行B中的结果,如下图
初始化Spark Streaming应用必须创建一个StreamingContext对象作为所有Spark Streaming函数
的入口
StreamingContext可以从SparkContext对象创建:
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
sc = SparkContext(master, appName)
ssc = StreamingContext(sc, 1)
appName参数是你的应用在集群UI展示的名称。
master是一个Spark、Mesos or YARN集群的URL,或者是在本地模式中字符串:“local[*]”。
实际上:在集群运行应用的时候,通常不会在程序中写死(硬编码)master,而是在通过spark-submit
启动应用时候指定。但是在本地测试和单元测试时,你可以传递“local[*]”在进程中运行Spark
Streaming 应用(在本地系统中指定核数)。
在Saprk内部,这些操作将创建一个可以通过
ssc.sparkContext访问的SparkContext(所以Spark函数的起点)。
批处理间隔(batch interval)必须建立在应用需求和可用的集群资源上,详情参考性能调优部分。
StreamingContext也可从已存在的SparkContext对象上创建
代码:
import org.apache.spark.streaming._
val sc = ... // existing SparkContext
val ssc = new StreamingContext(sc, Seconds(1))
在context对象定义之后,你需要做以下事情
1.通过创建输入DStream来定义输入资源
2.通过DStream的转换和输出操作来定义流的计算操作
3.通过streamingContext.start()开始接收数据,并处理数据
4.使用stramingContext.awaitTermination()等待执行结束。
5.数据处理操作可以通过streamingContext.stop()手动停止
请记住关键点:
1.一但一个context开始启动执行,不可再对context进行任何设置或增加流计算。
2.一但一个context停止,它将不能重新启动
3.同一时间在JVM上只有一个激活的StreamingContext
4.StreamingContext的stop()方法,同时也停止了SparkContext,如果仅停止
StreamingContext,设置Stop()的可选参数stopSparkContext值为false
5.如果之前的StreamingContext停止时没有停止SparkContext,那么这个SparkContext可
以重复利用创建新的StreamingContext,
Discretized Streams(DStreams)离散流
Discretized Streams(DStreams)是Spark Streaming 提供的基本抽象,他表示连续的数据流,
要么来自从资源接收的输入数据流,要么来自转换输入数据流时产生的执行数据流。实际上,
DStreams是一系列连续的RDDS(弹性数据集),RDDS是Spark对不可变的、分布式的数据集
合的抽象。在DStream中的每一个RDD包含一定时间隔的数据,如图所示:
任何对DStream的操作都将转换为对内部RDDs的操作。如前面的示例,将一个行流转换成单词
流,对每lines Stream中的每一个RDD进行flatMap操作产生单词流的RDDS,如下图所示:
这些内在的RDD转换由Spark引擎计算完成,这些DStream操作隐藏了大部分细节,并向开发者
提供高级API以便方便的开发应用。