继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

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

九州编程
关注TA
已关注
手记 475
粉丝 42
获赞 202

链接

和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依赖。例如,常用的依赖如下:

SourceArtifact
Kafkaspark-streaming-kafka-0-8_2.11
Flumespark-streaming-flume_2.11
Kinesisspark-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 SparkContextval 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包含一定时间间隔的数据,显示如下图。


webp

image.png


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


webp

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进行讨论。



作者:steanxy
链接:https://www.jianshu.com/p/210c4b536dd1


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP