Spark Streaming官方文档翻译Spark Streaming总览
Spark Streaming官方文档翻译基本概念之初始化与Dstream
Spark Streaming官方文档翻译基本概念之输入数据流和接收器
Spark Streaming官方文档翻译基本概念之转换操作
Spark Streaming官方文档翻译基本概念之输出操作
Spark Streaming官方文档翻译基本概念之sql与Mllib
Spark Streaming官方文档基本概念之缓存与检查点
Spark Streaming官方文档翻译基本概念之累加器、广播变量和检查点
Spark Streaming官方文档翻译Spark Streaming应用之部署,升级,监控
Spark Streaming官方文档翻译Spark Streaming性能调优
Spark Streaming官方文档翻译Spark Streaming容错
Spark Streaming官方文档翻译Spark Streaming +Kafka 集成指南
Spark Streaming官方文档翻译Spark Streaming自定义接收器
基本概念
输入数据流和接收器(Input DStreams and Receivers)
输入数据流是表示从数据源接收的输入数据流。在quick示例中,lines 是一个输入DStream,它表示从netcat服务器接收到的数据流。每个输入DStream(本节后面讨论的文件流除外)都与接收方(Scala doc、Java doc)对象相关联,接收方接收来自源的数据并将其存储在Spark内存中进行处理。
Spark Streaming 提供了两类内置流数据源。
- 基本资源:StreamingContext API中直接可用的资源。示例:文件系统和套接字连接。
- 高级资源:像Kafka, Flume, Kinesis等资源可以通过额外的工具类获得。如链接部分所述,这些需要针对额外依赖项进行链接。
我们将在本节后面讨论每个类别中的一些资源。
注意,如果希望在流应用程序中并行接收多个数据流,可以创建多个输入DStreams(将在性能调优部分进一步讨论)。这将创建多个接收器,同时接收多个数据流。但是请注意,Spark worker/executor是一个长时间运行的任务,因此它占用分配给Spark流应用程序的一个内核。因此,重要的需要记住的是,Spark流应用程序需要分配足够的核心(或线程,如果在本地运行)来处理接收到的数据,以及运行接收方。
重要点
- 在本地运行Spark流程序时,不要使用“local”或“local[1]”作为主URL。这两种方法都意味着只有一个线程将用于在本地运行任务。如果您使用基于接收器的输入DStream(例如sockets、Kafka、Flume等),那么将使用单个线程来运行接收器,不留下任何线程来处理接收到的数据。因此,在本地运行时,始终使用“local[n]”作为主URL,其中要运行小于n个接收方(有关如何设置主接收方的信息,请参阅Spark Properties)。
- 将逻辑扩展到在集群上运行,分配给Spark Streaming应用程序的内核数量必须大于接收器的数量。否则,系统将接收数据,但但却无法处理它。
基础源(Basic Sources)
我们已经在这个快速的示例中看到了ssc.socketTextStream(…),它根据通过TCP套接字连接接收的文本数据创建DStream。除了套接字之外,StreamingContext API还提供了将文件创建为输入源的方法。
文件源(File Streams)
对于从任何与HDFS API(即HDFS、S3、NFS等)兼容的文件系统上的文件中读取数据,可以通过 StreamingContext.fileStream[KeyClass ValueClass, InputFormatClass]创建DStream。
文件流不需要运行接收器,因此不需要为接收文件数据分配任何内核。
对于简单的文本文件,最简单的方法是StreamingContext.textFileStream(dataDirectory)。
streamingContext.fileStream[KeyClass, ValueClass, InputFormatClass](dataDirectory)
对于文件类型
streamingContext.textFileStream(dataDirectory)
如何监控目录
Spark Streaming将监视目录dataDirectory并处理在该目录中创建的任何文件。
- 可以监视一个简单的目录,比如“hdfs://namenode:8040/logs/”。位于该路径下的所有文件发现时将被处理。
- 可以提供POSIX glob模式,例如“hdfs://namenode:8040/logs/2017/*”。在这里,DStream将包含与模式匹配的目录中的所有文件。也就是说:它是目录的模式,而不是目录中的文件。
- 所有文件必须采用相同的数据格式。
- 一个文件被认为是基于其修改时间而不是创建时间的时间段的一部分。
- 处理后,对当前窗口内文件的更改将不会导致文件被重新读取。也就是说:更新被忽略。
- 目录下的文件越多,扫描更改所需的时间就越长——即使没有修改任何文件。
- 如果使用通配符来标识目录,如“hdfs://namenode:8040/logs/2016-*”,则重命名整个目录以匹配路径将该目录添加到受监视的目录列表中。只有修改时间在当前窗口内的目录中的文件才会包含在流中。
- 调用FileSystem.setTimes()来修正时间戳是在以后的处理窗口中获取文件的一种方法,即使它的内容没有改变。
使用对象存储作为数据源
像HDFS这样的“Full”文件系统倾向于在创建输出流时立即设置文件的修改时间。当一个文件被打开时,甚至在数据被完全写入之前,它就被包含在DStream中——在此之后,同一窗口内的文件更新将被忽略。也就是说:变更可能被遗漏,数据可能从流中被遗漏。
要确保在窗口中进行更改,请将文件写入未监视的目录,然后在关闭输出流之后立即将其重命名为目标目录。如果重新命名的文件在处理窗口时间内出现在扫描的目标目录中,则新数据将被处理。
相反,像Amazon S3和Azure Storage这样的对象存储通常有较慢的重命名操作,因为数据实际上是被复制的。此外,重命名的对象可能将rename()操作的时间作为其修改时间,因此可能不被认为是窗口的一部分,而新对象的创建时间意味着它们是窗口的一部分。
需要对目标对象存储进行仔细的测试,以验证存储的时间戳行为与Spark Streaming所期望的一致。直接写入目标目录可能是通过所选对象存储流数据的适当策略。
关于这个主题的更多细节,请参考Hadoop文件系统规范。
基于自定义接收器的流(Streams based on Custom Receivers)
可以使用通过自定义接收器接收的数据流创建DStreams。有关详细信息,请参阅自定义接收方指南。
将RDDs队列作为流
要使用测试数据测试Spark流应用程序,还可以使用streamingContext.queueStream(queueOfRDDs)创建基于RDDs队列的DStream。推入队列的每个RDD将被视为DStream中的一批数据,并像流一样进行处理。
有关套接字流和文件流的更多信息,请参见Scala的StreamingContext、Java的JavaStreamingContext和Python的StreamingContext中相关函数的API文档。
先进的来源(Advanced Sources)
Python API 从Spark 2.4.4开始,在这些源代码中,Kafka、Kinesis和Flume都可以在Python API中找到。
这类源需要与外部非spark库交互,其中一些具有复杂的依赖关系(例如Kafka和Flume)。因此,为了最小化与版本依赖冲突相关的问题,从这些源创建DStreams的功能已经转移到单独的库中,在必要时可以显式地链接到这些库。
注意,这些高级数据源在Spark shell中不可用,因此基于这些高级数据源的应用程序不能在shell中测试。如果您真的想在Spark shell中使用它们,那么您必须下载相应的Maven工件及其依赖项,并将其添加到类路径中。
这些先进的来源如下。
- kafka: Spark Streaming 2.4.4与Kafka代版本0.8.2.1或更高兼容。有关更多细节,请参阅Kafka集成指南。
- Flume: Spark Streaming 2.4.4与Flume 1.6.0兼容。有关更多细节,请参阅Flume集成指南。
- **kinesis **: Spark Streaming2.4.4与Kinesis客户端库1.2.1兼容。有关更多细节,请参阅kinesis集成指南。
定制源(Custom Sources)
Python API Python中还不支持这一点。
还可以从自定义数据源创建输入DStreams。您所要做的就是实现一个用户定义的接收器(请参阅下一节了解它是什么),它可以接收来自自定义源的数据并将其推入Spark。有关详细信息,请参阅自定义接收方指南。
接收器的可靠性(Receiver Reliability)
基于数据源的可靠性,可以划分两种数据源。数据源(如Kafka和Flume)允许确认传输的数据。如果从这些可靠来源接收数据的系统正确地确认接收到的数据,则可以确保不会由于任何类型的故障而丢失任何数据。这就导致了两种类型的接受者:
- 可靠的接收器 —— 一个可靠的接收器发送确认到一个可靠的来源时,数据已被分片接收和存储在Spark。
- 不可靠的接收方 —— 不可靠的接收方不会向源发送确认信息。这用于不支持确认的源,甚至可以用于不希望或不需要进入确认复杂性的可靠源。
如何编写可靠的接收器的详细信息在自定义接收器指南中进行了讨论。