SparkStreaming2.2(包含以前版本)+Kafka0.8
1. receiver模式
(不管需不需要都会传输数据)
receiver模式原理图
receiver模式流程:
- 在SparkStreaming程序运行起来后,Executor中会有receiver task接收kafka推送过来的数据。数据会被持久化,默认级别为MEMORY_AND_DISK_SER_2,这个级别也可以修改。
- receiver task对接收过来的数据进行存储和备份,这个过程会有节点之间的数据传输。(此时开启了WAL也会备份到HDFS上)
- 备份完成后去zookeeper中更新消费偏移量offset,
- 然后向Driver中的receiver tracker汇报数据的位置。
- 最后Driver根据数据本地化将task分发到不同节点上执行。
receiver模式中存在的问题
- 数据丢失问题
当 Driver进程挂掉后,Driver中的Executor进程都会被杀掉,若此时任务未计算完,会造成数据找不到的问题,相当于数据丢失.
- 解决:开启WAL(write ahead log)预写日志机制,在数据进行备份的时候会在hdfs上备份一份,这样就保证了数据的安全性,但是HDFS写入比较消耗性能,需要在数据备份完成之后才能进行zookeeper偏移量更新,位置汇报等等,会增加任务执行时间,我们可以将MEMORY_AND_DISK_SER_2 改成 MEMORY_AND_DISK_SER 来略微提升一点点性能.
- 开启WAL机制造成的数据重复消费问题
开启WAL机制,如果数据备份到HDFS上面后,此时要提交偏移量到zookeeper上,如果此时Driver挂掉了,则会造成数据偏移量提交失败.重新启动Driver之后,会先读取HDFS上数据,在读取zookeeper上的偏移量,然后读取kafka上的数据,此时会造成数据重复消费.
receiver代码
receiver的并行度设置
receiver的并行度是由spark.streaming.blockInterval来决定的,默认为200ms,假设batchInterval为5s,那么每隔blockInterval就会产生一个block,这里就对应每批次产生RDD的partition,这样5秒产生的这个Dstream中的这个RDD的partition为25个,并行度就是25。如果想提高并行度可以减少blockInterval的数值,但是最好不要低于50ms。
2. Driect模式
主动获取数据
Direct模式理解
SparkStreaming + kafka 的Driect模式就是将kafka看成存数据的一方,不是被动接收数据,而是主动去取数据。消费者偏移量也不是用zookeeper来管理,而是SparkStreaming内部对消费者偏移量自动来维护,默认消费偏移量是在内存中,当然如果设置了checkpoint目录,那么消费偏移量也会保存在checkpoint中。当然也可以实现用zookeeper来管理。
模式原理图:
Direct模式并行度设置
Direct模式的并行度是由读取的kafka中topic的partition数决定的。
Direct模式代码(见代码)
3. 相关配置
预写日志模式(WAL模式)
spark.streaming.receiver.writeAheadLog.enable 默认false没有开启
blockInterval (receiver模式下的参数)
控制并行度
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
4. 总结SparkStreaming2.2(包含以前) + Kafka0.8.2
Receiver模式
- receiver模式采用了Receiver接收器模式,需要一个线程一直接收数据,将数据接收到Executor中,默认存储级别是MEMORY_AND_DISK_SER_2
- receiver模式自动使用zookeeper管理消费者offset
- receiver模式底层读取Kafka 采用High Level Consumer API 实现,这种模式不关心offset,只要数据。
- receiver模式当Driver挂掉时,有丢失数据问题,可以开启WAL机制 避免丢失数据,但是开启之后加大了数据处理延迟 ,并且存在数据重复消费风险。
- receiver模式并行度由spark.streaming.blockInterval = 200ms ,可以减少这个参数增大并行度,最小不能低于50ms
- Receiver模式不被使用
- 被动将数据接收到Executor,当有任务堆积时,数据存储问题
- 这种模式不能手动维护消费者offset
- 开启WAL机制,性能会慢,不开又可能数据丢失,开了之后还可能数据重复消费
Direct模式
- direct模式没有使用receiver接收器模式,每批次处理数据直接获取当前批次数据处理
- direct模式没有使用zookeeper管理消费者offset,使用的是Spark自己管理,默认存在内存中,可以设置checkpoint,也会保存到checkpoint中一份
- direct模式底层读取Kafka使用 Simple Consumer API ,可以手动维护消费者offset
- direct模式并行度 与读取的topic的partition 一一对应
- 可以使用设置checkpoint的方式管理消费者offset, 使用StreamingContext.getOrCreate(ckDir,CreateStreamingContext) 恢复 。这种方式有两种缺点:
第一:当代码逻辑改变时,无法从checkpoint中来恢复offset.
第二:当从checkpoint中恢复数据时,有可能造成重复的消费,需要我们写代码来保证数据的输出幂等 开启事务等方法 - 如果代码逻辑改变,就不能使用checkpoint模式管理offset,可以手动维护消费者offset,可以将offset存储到外部系统,如redis
来源:CSDN
作者:BF-LoneSilverWind
链接:https://blog.csdn.net/digua930126/article/details/103795331