上课时,老师讲的几个学习Spark Streaming的几个要点,先放在前面作为指导思想
1)核心抽象:DStream
2)程序入口:sc = new SparkContext(); new StreamingContext(sc,Seconds(2))
3)算子的操作(map、flatMap、transform、updateStateByKey等)
PS:本文是Spark Streaming学习笔记,如有问题,欢迎留言指正~
PPS:配合实战代码食用会更香哦。 Spark Streaming企业级开发入门实战
一、了解下Spark Streaming
1.1 原理
Spark的各个子组件都是基于Spark-Core的,Spark Streaming在内部的处理机制是:先接收实时流的数据,并根据一定的时间间隔拆分成一批批的数据,这些批数据在Spark内核对应一个RDD实例,因此,流数据的DStream可以看成是一组RDDs,然后通过调用Spark核心的作业处理这些批数据,最终得到处理后的一批批结果数据。
从上面的描述可以看出,Spark Streaming本质上还是批处理,并不是真正的流处理(接收到一条数据处理一条),所以Spark Streaming的应用场景一般是对实时性要求不那么苛刻的准实时场景,这种场景下的延迟要求一般是秒级。
1.2 Spark Streaming的执行步骤
1)Spark Streaming是基于Spark-Core的,任务启动或初始化时,会启动一个Driver服务
2)Driver端会发送Receivers到executor里面,Receiver说白了就是一个接收器,用来接收数据(具体表现就是一个task任务)。 默认情况下,只有一个Receiver
3)每个Receiver会接收数据,并且会把数据生成block块(文件块的依据是200ms内的数据会在一个block块–(block interval))。接着把这些文件块存入到executor内存里面。为了保证数据安全,默认这些数据是有副本的。
4)Receiver会把block的信息(元数据的信息)发送给Driver
5)Driver端就会根据一定的时间间隔,把这些block封装成为一个RDD,然后进行计算。
1.3 Spark Streaming的特点
-
流批处理一体化
- Spark Streaming基于Spark Core的。Spark Core可以满足离线数据处理需求,Spark Streaming满足流式数据处理续期,可以减少技术学习的成本。
-
流式处理
- Spark Streaming是将流式计算分解成一系列短小的批处理作业,批处理引擎是Spark Core
- 整个流式计算根据业务的需求可以对中间的结果进行叠加或者存储到外部设备
-
高容错
- 每一个RDD都是一个不可变的分布式可重算的数据集,其记录着确定性的操作“血统”(lineage),所以只要输入数据是可容错的,那么任意一个RDD的分区(Partition)出错或者不可用,都是可以利用原始输入数据通过转换操作而重新算出的
-
低延迟
- 秒级延迟,(0.5 ~ 2s)
-
吞吐量高
- 吞吐量比Storm高2~5倍(来源网络,本人未验证)
二、 Spark Streaming的核心抽象–DStream
2.1 DStream介绍
DStream,代表持续性的数据流。这些数据流既可以通过外部输入源来获取,也可以通过现有的DStream的转换操作来获得。在内部实现上,DStream由一组时间序列上连续的RDD来表示。
2.2 Spark Streaming的作业机制
在Spark核心中,作业是由一系列具有依赖关系的RDD及作用于这些RDD上的函数所组成的操作链,在遇到行动操作时触发运行,向DAGScheduler提交并运行作业。
同样,在Spark Streaming中,对DStream进行的各种操作让他们之间构建起依赖关系。当遇到DStream使用输出操作时,这些依赖关系以及它们之间的操作会被记录到名为DStreamGraph的对象中表示一个作业。
- 这些作业注册到DStreamGraph并不会立即运行,而是等到SparkStreaming启动后,到达批处理时间时,才根据DStreamGraph生成作业处理该批处理时间内接收的数据。
- 在SparkStreaming 如果应用程序中存在多个输出操作,那么在批处理中会产生多个作业。
三、 几个比较重要的时间间隔参数
3.1 批处理间隔(Batch Duration)
在Spark Streaming中,数据采集数逐条进行的,但是数据处理是按批进行的,因此需要设置一个批处理间隔(batch Duration)。当超过批处理时间间隔的时候就会把采集的数据汇总起来成为一批数据交给系统去处理。
3.2 窗口间隔(Window Duration)和滑动间隔(Slide Duration)
对于窗口操作而言,在其窗口内部会有N个批处理数据,批处理数据的个数由窗口间隔(window duration)决定,其为窗口持续的时间,在窗口操作中只有窗口间隔满足了才会触发批数据的处理。
滑动间隔,指的是经过多长时间窗口滑动一次形成新的窗口,滑动窗口默认情况下和批次间隔的相同,而窗口间隔一般设置的要比他们俩都大。特别注意的是,窗口间隔和滑动间隔的大小一定得设置为批处理间隔的整数倍。
如下图所示,批处理间隔是1个时间单位,窗口间隔是3个时间单位,滑动间隔时2个时间单位。
对于初始的窗口time1 ~ time3,只有窗口间隔满足了才触发数据的处理。这里需要注意的是,初始的窗口有可能流入的数据没有撑满,但是随着时间的推进,窗口最终会被撑满。
当每2个时间单位后,窗口滑动一次 后,会有新的数据流入窗口,这时窗口会移去最早的2个时间单位的数据,而与最新的2个时间单位的数据进行汇总形成新的窗口(time3 ~ time5)
四、checkpoint
checkpoint记录程序运行的一些信息,是记录点。比较直观的一个应用就是数据总量或者总点击量的统计,如果程序重启了,使用checkpoint可以继续执行之前的累加效果
- 程序启动的时候,通过checkpoint恢复上一次的处理结果 (具体代码官网文档有)
- getOrCreate 如果之前存在的话,就直接从checkpoint中读取
http://spark.apache.org/docs/2.4.0/streaming-programming-guide.html#checkpointing
五、入门程序
步骤1:初始化程序入口
// local[2]-本地运行模式 2表示2个线程(最少2个线程,否则只能接收,不能处理数据)
SparkConf conf = new SparkConf().setAppName("Spark-demo").setMaster("local[2]”);
JavaStreamingContext jsc = new JavaStreamingContext(conf, Durations.seconds(1));
步骤2:通过数据源获取数据(数据的输入)
JavaInputDStream<ConsumerRecord<String, String>> messages =
KafkaUtils.createDirectStream(
jsc,
LocationStrategies.PreferConsistent(),
ConsumerStrategies.Subscribe(topics, kafkaParams));
步骤3:进行一些算子的操作,实现业务逻辑(数据的处理)
// 本质上讲,是从一个RDD变为一个新的RDD
// map 将函数应用于每个RDD的每个元素,返回值是新的RDD
JavaDStream<String> lines = messages.map(ConsumerRecord::value);
步骤4:数据的输出
// todoSomething
foreachRDD
步骤5:启动任务
jsc.start();
步骤6:等待任务结束
jsc.awaitTermination();
六、Spark Streaming常用的算子(未完待续……)
- transform
- updateStateByKey
- mapStateByKey
参考资料
- 《Spark Streaming企业级实战训练营》
- 《Spark快速大数据分析》
- 《图解Spark 核心技术与案例实战》
- Spark-2.4.0官网