摘要:学习SparkStreaming从官网的编程指南开始,由于Python编码修改方便不用打包,这里只整理python代码!
一、概述
Spark Streaming 是 Spark Core API 的扩展, 它支持弹性的, 高吞吐的, 容错的实时数据流的处理。数据可以通过多种数据源获取, 例如 Kafka, Flume, Twitter, ZeroMQ, Kinesis 以及 TCP sockets, 也可以通过例如 map, reduce, join, window 等的高级函数组成的复杂算法处理。最终, 处理后的数据可以输出到文件系统, 数据库以及实时仪表盘中。事实上, 还可以在 data streams(数据流)上使用机器学习以及图计算算法。
在内部, 它工作原理如下, Spark Streaming 接收实时输入数据流并将数据切分成多个 batch(批)数据, 然后由Spark引擎处理它们以生成最终的 stream of results in batches(分批流结果)。
Spark Streaming 提供了一个名为discretized stream或DStream的高级抽象, 它代表一个连续的数据流。DStream可以从数据源的输入数据流创建, 例如 Kafka, Flume 以及 Kinesis, 或者在其他 DStream 上进行高层次的操作来创建。在内部, 一个 DStream 是通过一系列的 RDDs 来表示。
本指南告诉你如何使用DStream来编写一个Spark Streaming程序。你可以使用 Scala,Java或者Python(Spark 1.2 版本后引进)来编写 Spark Streaming 程序。所有这些都在本指南中介绍. 您可以在本指南中找到标签, 让您可以选择不同语言的代码段.
注意: 在 Python 有些 API 可能会有不同或不可用. 在本指南, 您将找到 Python API 的标签来高亮显示不同的地方。
二、一个入门示例
在我们详细介绍如何编写你自己的 Spark Streaming 程序的细节之前, 让我们先来看一看一个简单的 Spark Streaming 程序的样子. 比方说, 我们想要计算从一个监听 TCP socket 的数据服务器接收到的文本数据(text data)中的字数. 你需要做的就是照着下面的步骤做.
首先, 我们导入StreamingContext,这是所有流功能的主要入口点。 我们创建了一个带有 2 个执行线程和间歇时间为 1 秒的本地 StreamingContext.
from pyspark import SparkContext from pyspark.streaming import StreamingContext # 创建一个具有两个工作线程(working thread)并且批次间隔为 1 秒的本地 StreamingContext . sc = SparkContext("local[2]", "NetworkWordCount") ssc = StreamingContext(sc, 1)
使用该 context, 我们可以创建一个代表从 TCP 源流数据的DStream,指定主机名(例如 localhost)和端口(例如 9999)。
# 创建一个将要连接到 hostname:port 的 DStream,如 localhost:9999 lines = ssc.socketTextStream("localhost", 9999)
上一步的这个 lines DStream 表示将要从数据服务器接收到的数据流. 在这个离散流(DStream)中的每一条记录都是一行文本(text). 接下来,我们想要通过空格字符拆分这些数据行成单词。
# 将每一行拆分成单词 words = lines.flatMap(lambda line: line.split(" "))
flatMap 是一种一对多的DStream操作,它会通过在源DStream中根据每个记录生成多个新纪录的形式创建一个新的DStream。在这种情况下,每一行都将被拆分成多个单词和代表单词DStream的单词流。下一步,我们想要计算这些单词:
# 计算每一个 batch(批次)中的每一个 word(单词) pairs = words.map(lambda word: (word, 1)) wordCounts = pairs.reduceByKey(lambda x, y: x + y) # 在控制台打印出在这个DStream中生成的每个 RDD 的前十个元素 wordCounts.print()
上一步的单词DStream进行了进一步的映射(一对一的转换)为一个 (word, 1) paris 的DStream,这个 DStream 然后被reduce来获得数据中每个批次的单词频率. 最后,wordCounts.print() 将会打印一些每秒生成的计数.
注意当这些行被执行的时候, Spark Streaming 仅仅设置了计算, 只有在启动时才会执行,并没有开始真正地处理。为了在所有的转换都已经设置好之后开始处理,我们在最后调用:
ssc.start() # Start the computation ssc.awaitTermination() # Wait for the computation to terminate
该部分完整的代码可以在 Spark Streaming 示例 NetworkWordCount 中找到。
如果你已经 下载 并且 构建 Spark, 您可以使用如下方式来运行该示例. 你首先需要运行 Netcat(一个在大多数类 Unix 系统中的小工具)作为我们使用的数据服务器。
$ nc -lk 9999
然后,在另一个不同的终端,你可以通过执行如下命令来运行该示例:
$ ./bin/spark-submit examples/src/main/python/streaming/network_wordcount.py localhost 9999
然后,在运行在 netcat 服务器上的终端输入的任何行(lines),都将被计算,并且每一秒都显示在屏幕上,它看起来就像下面这样:
# TERMINAL 1: # Running Netcat $ nc -lk 9999 hello world
# TERMINAL 2: RUNNING network_wordcount.py $ ./bin/spark-submit examples/src/main/python/streaming/network_wordcount.py localhost 9999 ... ------------------------------------------- Time: 2014-10-14 15:25:21 ------------------------------------------- (hello,1) (world,1) ...
三、基础概念
接下来,我们了解完了简单的例子,开始阐述 Spark Streaming 的基本知识。
(1)依赖
与 Spark 类似,Spark Streaming 可以通过 Maven 来管理依赖. 为了编写你自己的 Spark Streaming 程序,你必须添加以下的依赖到你的 SBT 或者 Maven 项目中.
Maven:
<dependency> <groupId>org.apache.spark</groupId> <artifactId>spark-streaming_2.11</artifactId> <version>2.2.0</version> </dependency>
针对从 Spark Streaming Core API 中不存在的数据源中获取数据,如 Kafka, Flume,Kinesis ,你必须添加相应的坐标 spark-streaming-xyz_2.11
到依赖中. 例如,有一些常见的依赖如下.
Source(数据源) Artifact(坐标)
Kafka spark-streaming-kafka-0-8_2.11
Flume spark-streaming-flume_2.11
Kinesis spark-streaming-kinesis-asl_2.11 [Amazon Software License]
(2)初始化 StreamingContext
为了初始化一个 Spark Streaming 程序, 一个 StreamingContext 对象必须要被创建出来,它是所有的 Spark Streaming 功能的主入口点。
一个 StreamingContext 对象可以从一个 SparkConf 对象中来创建.
from pyspark import SparkContext from pyspark.streaming import StreamingContext sc = SparkContext(master, appName) ssc = StreamingContext(sc, 1)
这个 appName 参数是展示在集群 UI 界面上的应用程序的名称. master 是一个 Spark, Mesos or YARN cluster URL, 或者一个特殊的 “local[*]” 字符串以使用 local mode(本地模式)来运行. 在实践中,当在集群上运行时,你不会想在应用程序中硬编码 master,而是 使用 spark-submit 来启动应用程序 , 并且接受该参数. 然而,对于本地测试和单元测试,你可以传递 “local[*]” 来运行 Spark Streaming 进程(检测本地系统中内核的个数). 请注意,做个内部创建了一个 SparkContext(所有 Spark 功能的出发点),它可以像 ssc.sparkContext 这样被访问.
这个 batch interval(批间隔)必须根据您的应用程序和可用的集群资源的等待时间要求进行设置. 更多详情请参阅 优化指南 部分.
在定义一个 context 之后,您必须执行以下操作.
♦ 通过创建输入 DStreams 来定义输入源.
♦ 通过应用转换和输出操作 DStreams 定义流计算(streaming computations).
♦ 开始接收输入并且使用 streamingContext.start() 来处理数据.
♦ 使用 streamingContext.awaitTermination() 等待处理被终止(手动或者由于任何错误).
♦ 使用 streamingContext.stop() 来手动的停止处理.
需要记住的几点:
♦ 一旦一个 context 已经启动,将不会有新的数据流的计算可以被创建或者添加到它。.
♦ 一旦一个 context 已经停止,它不会被重新启动.
♦ 同一时间内在 JVM 中只有一个 StreamingContext 可以被激活.
♦ 在 StreamingContext 上的 stop() 同样也停止了 SparkContext 。为了只停止 StreamingContext ,设置 stop() 的可选参数,名叫 stopSparkContext 为 false.
♦ 一个 SparkContext 就可以被重用以创建多个 StreamingContexts,只要前一个 StreamingContext 在下一个StreamingContext 被创建之前停止(不停止 SparkContext).