Spark学习笔记 --- SparkStreaming 中基本概念

版权声明:学习交流为主,未经博主同意禁止转载,禁止用于商用。 https://blog.csdn.net/u012965373/article/details/68489782

StreamingContext

StreamingContext 是Spark Streaming程序的入口点,正如SparkContext是Spark程序的入口点一样。

StreamingContext中维护了一个SparkContext实例,你可以通过 ssc.sparkContext 来访问它。该SparkContext实例要么在创建StreamingContext时被传入,要么在StreamingContext内部根据传入的SparkConf进行创建,这取决于你所使用的StreamingContext构造函数。

关于DStream

Spark Streaming将流数据抽象为离散化流(discretized stream),即 DStream 。DStream在内部被表示为一个连续的RDD序列,每一个RDD包含了一个固定时间间隔内数据源所产生的数据,如下图所示。


对DStream所进行的操作将被转换为对底层RDD的操作。例如,在前面的流数据单词计数示例程序中, lines.flatMap(_.split(" ")) 语句中的 flatMap 算子就被应用到lines DStream中的RDD以生成words DStream中的RDD,如下图所示。


InputDStream和ReceiverInputDStream

InputStream是所有输入流的抽象基类。 这个类提供start()和stop()方法,这两个方法被Spark 流系统用来启动开始接收数据和停止接收数据。

如果输入流仅在运行在driver结点的服务和线程产生的新数据生成RDD,那么可能直接继承这个InputStream。以FileINputDStream为例,它是InputStream的一个子类,在driver端监控一个HDFS目录,如果有新文件生成,则用新文件生成RDDs。 

如果实现的输入流需要在工作结点运行一个接收器,使用[[org.apache.spark.streaming.dstream.ReceiverInputDStream]]作为父类。

ReceiverInputDStream是一个抽像类,用于需要在工作结点启动一个接收器来接收外部数据。 ReceiverInputDStream的具体实现必须定义getReceiver方法来得到一个[[org.apache.spark.streaming.receiver.Receiver]] 对象。Receiver对象会发送到工作结点来接收数据。

 我们也可以创建多个InputDStream来连接多个数据源,其中的ReceiverInputDStream都将启动Receiver来接收数据。 一个Spark Streaming应用程序应该分配足够多的核心(local模式下是线程)去运行receiver(s)并处理其接收的数据。当我们以本地模式运行Spark Streaming程序时,master URL不能指定为 local 或者 local[1] (Spark Streaming会启动一个线程运行receiver,只有一个线程将导致没有线程来处理数据),而应该是 local[n] ,这个n应该大于receiver的个数。在集群中运行Spark Streaming程序时,同样道理,也需要分配大于receiver的个数的核心数。

基本数据源

Spark Streaming提供了从很多数据源获取流数据的方法,一些基本的数据源可以通过StreamingContext API直接使用,主要包括:文件系统、网络连接、Akka actors等。

文件数据流

StreamingContext提供了从兼容于HDFS API的所有文件系统中创建文件数据输入流的方法,如下:

ssc.fileStream[KeyClass, ValueClass, InputFormatClass](dataDirectory)

文件流没有receiver。Spark Streaming将监控对应目录(但不支持嵌套目录),并处理在该目录中创建的任何文件(以 . 开头的将被忽略)。监控目录中的文件必须有相同的数据格式。监控目录中的文件如果被修改(比如以append方式写入),这些修改将不会被读取,因此正确的方式应该是先在其他目录中写好这些文件并将其移动或者重命名到该监控目录。

对于简单的文本文件,可以使用更简单的方法,如下:

ssc.textFileStream(dataDirectory)

网络数据流

网络连接流可以使用 ssc.socketStream() 或 ssc.socketTextStream() 创建。

Akka Actor流

可以通过 ssc.actorStream() 创建一个从Akka actor接收数据流的ReceiverInputDStream。

RDD序列流

我们也可以用 ssc.queueStream() 创建一个基于RDD序列的InputDStream。序列中的每一个RDD将被作为DStream中的一个数据批,这通常在测试你的Spark Streaming程序时非常有用。

高级数据源

对于Kafka、Flume、Kinesis、Twitter等这些高级数据源,则需要添加外部依赖。

自定义数据源

你也可以自定义数据源,只需要实现一个自己的receiver从自定义数据源接收数据并将其推送到Spark。

Receiver可靠性

依据可靠性可将Receiver分为两类。 可靠Receiver 带有传输确认机制(ACK机制),可以确保数据在传输过程中不会丢失,Kafka和Flume等在ACK机制开启的情况下就是可靠的。 不可靠Receiver 不带有传输确认机制,包括不支持ACK机制和支持ACK但关闭的情形。

window

Spark Streaming也提供了基于窗口的计算,它允许你在一个滑动窗口上使用转换操作,滑动窗口如下图所示。


窗口是基于时间滑动的,窗口操作新形成的DStream中的每一个RDD包含了某一滑动窗口中的所有数据。任何窗口操作都需要指定如下两个参数:

  • 窗口长度:它必须是源DStream批处理间隔的整数倍。
  • 滑动间隔:它必须是源DStream批处理间隔的整数倍。

一些常用的窗口操作算子如下:

Transformation Meaning
window ( windowLength , slideInterval ) Return a new DStream which is computed based on windowed batches of the source DStream.
countByWindow ( windowLength , slideInterval ) Return a sliding window count of elements in the stream.
reduceByWindow ( func , windowLength , slideInterval ) Return a new single-element stream, created by aggregating elements in the stream over a sliding interval using func . The function should be associative so that it can be computed correctly in parallel.
reduceByKeyAndWindow ( func , windowLength , slideInterval , [ numTasks ]) When called on a DStream of (K, V) pairs, returns a new DStream of (K, V) pairs where the values for each key are aggregated using the given reduce function func over batches in a sliding window. Note: By default, this uses Spark’s default number of parallel tasks (2 for local mode, and in cluster mode the number is determined by the config property spark.default.parallelism ) to do the grouping. You can pass an optional numTasks argument to set a different number of tasks.
reduceByKeyAndWindow ( func , invFunc , windowLength , slideInterval , [ numTasks ]) A more efficient version of the above reduceByKeyAndWindow() where the reduce value of each window is calculated incrementally using the reduce values of the previous window. This is done by reducing the new data that enters the sliding window, and “inverse reducing” the old data that leaves the window. An example would be that of “adding” and “subtracting” counts of keys as the window slides. However, it is applicable only to “invertible reduce functions”, that is, those reduce functions which have a corresponding “inverse reduce” function (taken as parameter invFunc ). Like in reduceByKeyAndWindow , the number of reduce tasks is configurable through an optional argument. Note that checkpointing must be enabled for using this operation.
countByValueAndWindow ( windowLength , slideInterval , [ numTasks ]) When called on a DStream of (K, V) pairs, returns a new DStream of (K, Long) pairs where the value of each key is its frequency within a sliding window. Like in reduceByKeyAndWindow , the number of reduce tasks is configurable through an optional argument.

需要强调的是,上述某些操作(如 reduceByWindow 和 reduceByKeyAndWindow 等)有一些特殊形式,通过只考虑新进入窗口的数据和离开窗口的数据,让Spark增量计算归约结果。这种特殊形式需要额外提供一个规约函数的逆函数,比如 + 对应的逆函数为 - 。对于较大的窗口,提供逆函数可以大大提高执行效率。


展开阅读全文

没有更多推荐了,返回首页