Spark Streaming概述
Spark Streaming是对于Spark core API的拓展(因为是基于Spark core,所以安装完Spark就能直接使用Spark Streaming),从而支持对于实时数据流的可拓展,高吞吐量和容错性流处理。数据可以由多个源取得,例如:Kafka,Flume,Twitter,ZeroMQ,Kinesis或者TCP接口,同时可以使用由如map,reduce,join和window这样的高层接口描述的复杂算法进行处理。最终,处理过的数据可以被推送到文件系统,数据库和实时屏幕。实际上,您可以在数据流上应用Spark的 机器学习和 图形处理算法。
在内部,它的工作方式如下。Spark Streaming接收实时输入数据流,并将数据分成批处理,然后由Spark引擎进行处理,以生成批处理的最终结果流。
Spark Streaming提供了称为离散流或DStream的高级抽象,它表示连续的数据流。可以根据来自Kafka,Flume和Kinesis等来源的输入数据流来创建DStream,也可以通过对其他DStream应用高级操作来创建DStream。在内部,DStream表示为一系列的RDD 。
常用实时流处理框架:Strom,Spark Streaming,Flink,Kafka Stream
Strom和SparkStreaming的对比:
1).Strom是真正意义上的的流处理,时延相比SparkStreaming较低,而SparkStremming是将接受的实时流数据,按照指定的时间间隔拆成一个个RDD,在每个RDD中以批处理的形式处理数据。本质上还是批处理。
2).Storm会通过messageId的方式全局追踪和记录每一条记录,并通过ack/fail机制确保每条数据至少被处理一次(也可能是多次),而SparkStream应用程序只需要批处理级别对记录进行追踪,他能保证每个批处理记录仅仅被处理一次。
3).由于SparkStreming是运行在Spark平台上的无需单独安装,可以和批处理SparkSql,机器学习等其他其框架结合起来使用。
核心概念
初始化StreamingContext
要初始化Spark Streaming程序,必须创建StreamingContext对象,该对象是所有Spark Streaming功能的主要入口点。
pyspark.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或YARN群集URL或特殊的“ local [*]”字符串,以在本地模式下运行。实际上,当在集群上运行时,您将不希望master
在程序中进行硬编码,而是在其中启动应用程序spark-submit
并在其中接收。但是,对于本地测试和单元测试,您可以传递“ local [*]”以在内部运行Spark Streaming(检测本地系统中的内核数)。
必须根据应用程序的延迟要求和可用的群集资源来设置批处理间隔。有关 更多详细信息,请参见性能调整部分。
定义上下文后,必须执行以下操作。
- 通过创建输入DStream定义输入源。
- 通过将转换和输出操作应用于DStream来定义流计算。
- 开始接收数据并使用进行处理
streamingContext.start()
。 - 等待使用停止处理(手动或由于任何错误)
streamingContext.awaitTermination()
。 - 可以使用手动停止处理
streamingContext.stop()
。
要记住的要点:
- 一旦启动上下文,就无法设置新的流计算或将其添加到该流计算中。
- 上下文一旦停止,就无法重新启动。
- JVM中只能同时激活一个StreamingContext。
- StreamingContext上的stop()也会停止SparkContext。要仅停止的StreamingContext,设置可选的参数
stop()
叫做stopSparkContext
假。 - 只要在创建下一个StreamingContext之前停止(不停止SparkContext)上一个StreamingContext,即可将SparkContext重新用于创建多个StreamingContext。
Discretized Streams (DStreams)
Discretized Streams或DStream是Spark Streaming提供的基本抽象。它表示连续的数据流,可以是从源接收的输入数据流,也可以是通过转换输入流生成的已处理数据流。在内部,DStream由一系列连续的RDD表示,这是Spark对不可变的分布式数据集的抽象(有关更多详细信息,请参见Spark编程指南)。DStream中的每个RDD都包含来自特定间隔的数据,如下图所示。
在DStream上执行的任何操作都转换为对基础RDD的操作。例如,在较早的将行流转换为单词的示例中,将flatMap
操作应用于lines
DStream中的每个RDD 以生成DStream的 words
RDD。如下图所示。
这些基础的RDD转换由Spark引擎计算。DStream操作隐藏了大多数这些细节,并为开发人员提供了更高级别的API,以方便使用。这些操作将在后面的部分中详细讨论。
案例实战
可以参考这个老哥的博客,Spark学习实例(Python):输入源实时处理 Input Sources Streaming
api使用方法可以查看文档 http://spark.apache.org/docs/latest/api/python/pyspark.streaming.html
from pyspark import SparkContext
from pyspark.streaming import StreamingContext
sc = SparkContext(appName="inputSourceStreaming", master="local[4]")
ssc = StreamingContext(sc, 5)
# lines=ssc.textFileStream("file:///opt/datas/ss")
"""textFileStream(目录)
创建一个输入流,该流监视与Hadoop兼容的文件系统中的新文件,
并将其读取为文本文件。必须通过从同一文件系统中的其他位置“移动”文件来将文件写入受监视的目录。
文件名以.开头被忽略。"""
lines = ssc.socketTextStream("localhost", 9998)
"""您首先需要通过使用以下命令将Netcat(在大多数类Unix系统中找到的一个小实用程序)作为数据服务器运行
$ nc -lk 9999"""
counts=lines.flatMap(lambda x:x.split(" ")).map(lambda x:(x,1)).reduceByKey(lambda a,b:a+b)
counts.pprint()
ssc.start()
ssc.awaitTermination()