SparkStreaming知识点注意事项

本文介绍了SparkStreaming的原理和特点,对比了它与Storm的差异。详细讲解了SparkStreaming的处理流程,包括receiver模式下的数据接收、DStream转换、算子应用如foreachRDD、updateStateByKey和窗口操作。此外,还探讨了Driver HA的实现以及SparkStreaming与Kafka的结合,包括receiver模式和Direct模式的数据丢失与并行度设置问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1. SparkStreaming简介


SparkStreaming是流式处理框架,是Spark API的扩展,支持可扩展、高吞吐量、容错的准实时数据流处理,实时数据的来源可以是:Kafka, Flume, Twitter, ZeroMQ或者TCP sockets,并且可以使用高级功能的复杂算子来处理流数据。例如:map,reduce,join,window 。最终,处理后的数据可以存放在文件系统,数据库等,方便实时展现。
在这里插入图片描述

2. SparkStreaming&Storm的区别

1)Storm是纯实时的流式处理框架,SparkStreaming是准实时的处理框架(微批处理)。因为微批处理,SparkStreaming的吞吐量比Storm要高。
2)Storm 的事务机制要比SparkStreaming的要完善。
3)Storm支持动态资源调度。(spark1.2开始和之后也支持)
4)SparkStreaming擅长复杂的业务处理,Storm不擅长复杂的业务处理,擅长简单的汇总型计算。

3. SparkStreaming流程

在这里插入图片描述
*

一批一批的处理数据,每几秒会在每几分处理一批数据,

1)数据源Client发送数据到Socker Server服务器的某个端口
2)在Spark Streaming中的receiver task一直监听Socker Server端口的数据。
3)每隔一段时间将监听到的数据封装成一个batch。(这段时间是自己设置的)
4)batch被封装成一个RDD,然后又被封装成一个DStream。
5)然后通过转换算子进行逻辑处理,变成另外一个DStream。
6)再经过output Opoertor算子(类似触发算子),得到结果。

总结

Spark Stream的receiver task 会7*24小时一直运行,将接收到的数据保存起来,每隔batchInterval的时间将数据封装成一个batch,再封装成RDD,最后封装成一个DStream。

问题:

假设计算一批数据需要6秒,每5秒接收一批数据,随着时间的增长,数据的堆积会越来越严重,如果数据保存在内存中,就会导致OOM,并且影响性能。(如果设置StorageLevel 包含disk,则内存存放不下的数据就会溢写到disk,加大延迟)

在代码中需要注意的事项:

1)在receiver模式下接收数据,local的模拟线程必须大于等于2,一个线程用来接收数据,另一个线程用来执行job。
2)Durations时间设置就是我们接收的延迟度,这个需要根据集群的资源情况一个任务的执行情况来调节。
3)所有的代码逻辑完成后要有一个Output operation类算子。

4)JavaStreamingContext(),Streaming框架启动后不能再次添加业务逻辑。
5)JavaStreamingContext.stop()无参的stop方法将SparkContext一同关闭,stop(fales),不会关闭SparkContext。

6)JavaStreamingContext.stop()停止后不能再调用start。


4. SparkStreaming算子


1.foreachRDD

作用:

将DStream 转换为一个个底层的RDD。foreachRDD算子之内,获取到的RDD算子之外的代码是在Driver端执行的。必须对抽取出来的RDD执行action类算子,代码才能执行。
在原有的逻辑之外(executor端)添加一些逻辑(在Driver端),每当执行原有的逻辑之前,都执行这个逻辑,不需要触发

注意:

RDD之外的这些代码,是在driver运行的,每启动一个job都会执行这里的代码
RDD的处理,必须最后有触发算子,才能启动整个任务的计算

2.transform

作用:

和transform类型,将DStream的操作转换为RDD进行操作,区别:该api没有返回值
3.updateStateByKey

updateStateByKey是transformation算子

作用:

把之前的计算结果和当前这一批的数据合成

weSparkStreaming中每一个Key维护一份state状态,state类型可以是任意类型的,可以是一个自定义的对象,更新函数也可以是自定义的。
通过更新函数对该key的状态不断更新,对于每一个新的batch而言,SparkStreaming会在使用updateStateByKey的时候为已经存在的key进行state的状态更新

使用到updateStateByKey要开启checkpoint机制和功能

那么问题:多久会将内存中的数据写入到磁盘一份?

1)如果batchInterval设置的时间小于10秒,那么10秒写入磁盘一份。
2)如果batchInterval设置的时间大于10秒,那么就会batchInterval时间间隔写入磁盘一份。

4. 窗口操作

应用场景:

每隔五秒计算一批数据,计算十五秒的数据

reduceByKeyAndWindow()方法的两个参数

windowDuration:
窗户的宽度;必须是这个DStream的批处理间隔的倍数
slideDuration:
窗口的滑动间隔(即,新DStream生成RDDs的时间间隔);必须是这个DStream的批处理间隔的倍数

JavaPairDStream<String, Integer> searchWordCountsDStream =
        searchWordPairDStream.reduceByKeyAndWindow(new Function2<Integer, Integer, Integer>() {
            @Override
            public Integer call(Integer v1, Integer v2) throws Exception {
                System.out.println(v1 + " : " + v2);
                return v1 + v2;
            }
        },Durations.seconds(15),Durations.seconds(5));

window优化:

没有优化的窗口函数可以不设置checkpoint目录。
优化的窗口函数必须设置checkpoint目录
每次都是十五秒的值相加,有重复的计算;所以进行优化:
0-15的值减去0-5的值加上15-20的值。

JavaPairDStream<String, Integer> searchWordCountsDStream =
            searchWordPairDStream.reduceByKeyAndWindow(new Function2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer v1, Integer v2) throws Exception {
                    System.out.println("v1:" + v1 + " v2:" + v2 + "  ++++++++++");
                    return v1 + v2;
                }
            }, new Function2<Integer, Integer, Integer>() {
                @Override
                public Integer call(Integer v1, Integer v2) throws Exception {
                    System.out.println("v1:" + v1 + " v2:" + v2 + "------------");
                    return v1 - v2;
                }
            }, Durations.seconds(15), Durations.seconds(5));

5. saveAsTextFiles算子:保存结果到本地,MySQL等

5.Driver HA

因为SparkStreaming是7*24小时运行,Driver只是一个简单的进程,有可能挂掉,所以实现Driver的HA就有必要(如果使用的Client模式就无法实现Driver HA ,这里针对的是cluster模式)。
Yarn平台cluster模式提交任务,AM(AplicationMaster)相当于Driver,如果挂掉会自动启动AM。这里所说的DriverHA针对的是Spark standalone和Mesos资源调度的情况下。

实现Driver的高可用有两个步骤:

1)提交任务层面,在提交任务的时候加上选项 --supervise,当Driver挂掉的时候会自动重启Driver。
2)代码层面,使用JavaStreamingContext.getOrCreate(checkpoint路径,JavaStreamingContextFactory)

Driver中元数据包括:

创建应用程序的配置信息。
DStream的操作逻辑。
job中没有完成的批次数据,也就是job的执行进度。

6. SparkStreaming+Kafka

1. receiver模式

在这里插入图片描述
执行流程

SparkStreaming启动,Executor中的receiver tasks 接收kafka推送过来的数据
数据被持久化到其他节点的Exevutor中形成data数据,默认级别为MEMORY_AND_DISK_SER_2 receiver task提交偏移量到zookeeper中。
将备份的数据位置汇报给Driver的receiver Tracker。Driver中就掌握了数据的位置
Drvier发送task去执行

数据丢失问题

当Driver进程挂掉后,Driver下的Executor都会被杀掉,当更新完zookeeper消费偏移量的时候,Driver如果挂掉了,就会存在找不到数据的问题

解决

开启WAL(write ahead log)(配置为spark.streaming.receiver.writeAheadLog.enable 默认false没有开启)
预写日志机制,在接受过来数据备份到其他节点的时候,同时备份到HDFS上一份。
在driver突发宕机,我们会重启driver,那么driver会先到hdfs上检测未被计算的数据,然后将之先计算,计算完成后,再到zookeeper上面读取偏移量,然后继续往后计算数据。

注意:

这种方式,因为多了一步数据上传到hdfs上面,hdfs又会是内部备份,高延迟,最终会使我们的任务延迟度增大。

优化:

将数据的MEMORY_AND_DISK_SER_2方式改成MEMORY_AND_DISK,不需要额外备份

WAL机制导致重复消费问题

当启动WAL机制时,若在数据存在hdfs后,提交偏移量到zookeeper之前,这个时间点,driver挂掉,则会造成数据重复计算。因为,当前driver重启之前,会先读取hdfs的数据做计算,然后再去zookeeper上面读取偏移量,此时就造成了数据重复读取。

并行度设置

receiver的并行度是由spark.streaming.blockInterval来决定的,默认为200ms,假设batchInterval为5s,那么每隔blockInterval就会产生一个block,这里就对应每批次产生RDD的partition,这样5秒产生的这个Dstream中的这个RDD的partition为25个,并行度就是25。如果想提高并行度可以减少blockInterval的数值,但是最好不要低于50ms。
2. Direct模式

SparkStreaming+kafka 的Driect模式

此种模式,kafka偏移量有spark自己保存在内存中,也通过checkpoint进行持久化,放到磁盘层面
Dstream的分区数等于kafka topic的分区数

并行度设置

Direct模式的并行度是由读取的kafka中topic的partition数决定的。
3. 相关配置

blockInterval:
spark.streaming.blockInterval默认200ms

反压机制:
spark.streaming.backpressure.enabled 默认false

接收数据速率:

Receiver模式:
spark.streaming.receiver.maxRate 默认没有设置
Direct模式:
spark.streaming.kafka.maxRatePerPartition

优雅的停止sparkstream :
spark.streaming.stopGracefullyOnShutdown设置成true
kill -15/sigterm driverpid

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值