[译]Spark Streaming编程指南(二)

链接

和Spark类似,Spark Streaming通过Maven Central提供。为编写Spark Streaming程序,需要添加下面的依赖到你的SBT或者Maven工程中。

<dependency>
    <groupId>org.apache.spark</groupId>
    <artifactId>spark-streaming_2.11</artifactId>
    <version>2.1.1</version>
</dependency>
libraryDependencies += "org.apache.spark" % "spark-streaming_2.11" % "2.1.1"

从Kafka,Flume和Kinesis获取数据不在Spark Streaming的核心API中,需要添加相应的artifact 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

更新列表请参见Maven repository

初始化StreamingContext

初始化Spark Streaming程序,必须创建StreamingContext对象,作为Spark Streaming程序的主入口点。

SparkConf对象创建StreamingContext对象。

import org.apache.spark._
import org.apache.spark.streaming._

val conf = new SparkConf().setAppName(appName).setMaster(master)
val ssc = new StreamingContext(conf, Seconds(1))

appName参数是应用程序名称,显示在集群UI上。master是一个Spark, Mesos或YARN集群URL,或者一个特殊的"local[]"字符串,以本地模式运行。实际上,当运行在集群上时,是不希望在程序中硬编码master的,而是使用spark-submit启动应用程序
接收master参数。不过为了本地测试和单元测试,可以传"local[
]"来运行Spark Streaming(在本地系统检测CPU核数)。注意,这里内部创建了一个SparkContext(Spark程序的起始点),可以通过ssc.sparkContext访问。

批时间间隔必须根据应用程序的延迟需求和集群可用资源来设置。具体参见性能调优

StreamingContext对象也可以通过已经存在的SparkContext对象创建。

import org.apache.spark.streaming._

val sc = ...                // existing SparkContext
val ssc = new StreamingContext(sc, Seconds(1))

上下文定义完成后,必须做以下事情。

  1. 通过创建输入DStream定义输入源。
  2. 通过在DStream上应用转换和输出操作定义流计算。
  3. 开始接收数据并使用streamingContext.start()进行处理。
  4. 使用streamingContext.awaitTermination()等待处理结束(手动或者因为错误结束)。
  5. 可使用streamingContext.stop()手动停用处理过程。

需要记住的几点:

  • 一旦上下文启动,就不能像其添加新的流计算了。
  • 一旦上下文停用,不能重启。
  • 同一时间再JVM中只能有一个StreamingContext处于活跃状态。
  • StreamingContext的stop()方法也会停用SparkContext。只想停用StreamingContext,设置stop()方法的可选参数stopSparkContext为false。
  • SparkContext可以进行重用,创建多个StreamingContext,只要在创建下一个StreamingContext之前停用了前一个StreamingContext(但是没有停用SparkContext)即可。

离散流(DStreams)

DStream是Spark Streaming提供的基本抽象。代表一个连续的数据流,要么是从源接收的输入数据流,要么是转换输入流生成的处理过的数据流。在Spark内部,DStream代表一系列连续的RDD(不可变的分布式数据集,参见Spark编程指南(二)。DStream中的每个RDD包含一定时间间隔的数据,显示如下图。

image.png

应用在DStream的任何操作都会转换为潜在RDD的操作。例如,在前面例子中将每行的数据流转换为单词,flatMap操作应用在lines DStream中的每个RDD上,生成words DStream的RDD。显示如下图。

image.png

这些潜在的RDD转换由Spark engine进行计算。DStream操作会隐藏大部分这些细节,然后提供给开发者一个高层API方便使用。这些操作会在之后进行详细介绍。

输入DStreams和Receivers

输入DStream代表从源接收的输入数据流。在前面快速示例中,lines就是输入DStream,它代表了从netcat服务器接收的数据流。每个输入DStream(除了文件流,会在下面进行讨论)都会关联一个ReceiverScala doc, Java doc)对象,这个对象接收来自源的数据并将数据存储在Spark的内存中供后续处理。

Spark Streaming提供两类内置的源。

  • Basic sources:在StreamingContext API中直接可用。例如:文件系统和socket连接。
  • Advanced sources:如Kafka,Flume,Kinesis等。通过额外的工具类可用。这些需要链接到额外的依赖项,这个之前已经讨论过。

接下来讨论每个类别中的一些源。

注意,如果你想在streaming应用程序中并行接收多个数据流,可以创建多个输入DStream(在之后性能调优中进行讨论)。这样会创建多个receiver同时接收多个数据流。但是需要注意的是Spark worker/executor是长线任务,它会占用分配给Spark Streaming应用程序的一个CPU核。因此,要记住Spark Streaming应用程序需要分配足够的CPU核(或线程,如果在本地运行)来处理接收到的数据以及运行receiver。

需要记住的几点

  • 当本地运行Spark Streaming程序时,不要使用"local"或者"local[1]"作为master URL。这意味着本地只有一个线程用来运行任务。如果你使用基于receiver的输入DStream(例如sockets,Kafka,Flume等等),单线程会用于运行receiver,没有线程会用于处理接收到的数据。因此,当本地运行时,要使用"local[n]"作为master URL,其中n大于receiver的数量(可参考Spark Properties了解如何设置master)。
  • 将逻辑扩展到集群上运行,分配给Spark Streaming应用程序的核数必须比receiver的数量多。否则系统会接收数据,但不能处理数据。

Basic Sources
在前面的示例中我们已经看到过ssc.socketTextStream(...),从TCP socket连接接收文本数据并创建一个DStream。处理sockets,StreamingContext API还提供了创建以文件作为源的DStream。

  • File Streams:从任意兼容HDFS API的文件系统(如HDFS, S3, NFS等等)的文件中读取数据,可以用如下方式创建DStream:
 streamingContext.fileStream[KeyClass, ValueClass, InputFormatClass](dataDirectory)

Spark Streaming会监控目录dataDirectory,处理任意在那个目录中创建的文件(不支持写入嵌套目录中的文件)。请注意:

  • 文件必须是相同数据格式。
  • 文件必须在dataDirectory中创建,通过原子级地移动或重命名文件到数据目录的方式。
  • 一旦移动,文件必须不能修改。如果文件正在不断地进行追加,那么新数据不会被读取。

对于简单文本文件,有一个更简单的方法streamingContext.textFileStream(dataDirectory)。文件流不会要求运行receiver,因此不需要分配CPU核。

  • 基于自定义Receiver的流:可以通过自定义receiver接收数据流来创建DStream。详细请参见Custom Receiver Guide

  • RDD队列作为流:对于使用测试数据测试一个Spark Streaming应用程序来说,可以基于RDD队列来创建DStream,使用streamingContext.queueStream(queueOfRDDs)。添加到队列中的每个RDD都会被当做DStream中一个批次的数据,像数据流一样进行处理。

对于来自socket和文件数据流的更多细节请参见相关的API文档,scala请参见StreamingContext,Java请参见JavaStreamingContext,Python请参见StreamingContext

Advanced Sources
这个分类的源要和外部非Spark库交互,其中一些需要复杂的依赖(如Kafka和Flume)。因此,为了尽量减少和依赖库版本冲突的问题,从这些源创建DStream的功能移到了单独的库中,必要时可以显式链接。

注意这些高级源在Spark shell中不可用,因此基于高级源的应用程序不能在shell中测试。如果想要在Spark shell中使用高级源,需要在下载对应的Maven artifact’s JAR以及其依赖的库,然后添加到classpath中。

一些高级源如下:

Custom Sources
输入DStream也可以通过自定义数据源创建。你需要实现用户定义的receiver(下面会进行说明)用于接收自定义源的数据并将数据存储到Spark中。具体参见Custom Receiver Guide

Receiver可靠性
有两类基于可靠性的数据源。数据源(如Kafka和Flume)允许确认传输的数据。如果系统从这些能确认数据正确接收的可靠源接收数据,则可以确保不会有数据因为任何类型的失败而丢失数据。下面是两类receiver:

  1. 可靠Receiver - 当数据已经接收并且按照副本要求存储到Spark中时,可靠receiver会正确发送确认信息给可靠数据源。
  2. 不可靠Receiver - 不可靠数据源不能发送确认信息给数据源。这类receiver用于不支持确认的数据源,或者对于可靠数据源,不想或不需要进行确认。

如何编写可靠receiver在中Custom Receiver Guide进行讨论。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,319评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,801评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,567评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,156评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,019评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,090评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,500评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,192评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,474评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,566评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,338评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,212评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,572评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,890评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,169评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,478评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,661评论 2 335

推荐阅读更多精彩内容