spark发行版笔记4Spark Streaming事务处理彻底掌握

时间:2023-04-26 22:45:22

Spark Streaming事务处理彻底掌握

感谢DT大数据梦工厂支持提供以下内容,DT大数据梦工厂专注于Spark发行版定制。

内容概括:

1Exactly once

2 输出不重复

1 正如银行转账业务一样,如果你给一个朋友转账一次,银行的系统必须保证此次的转账数据有且只能处理一次,不能出现另外的情况。事务的意思就是保证数据有且只能处理一次。

而Spark Streaming流处理在事务处理方面也是做得非常好的,并且这一部分内容也是非常重要的。

所谓一图胜千言,我们就来画一张图吧。

整个数据在Driver和Executor上的分布如下

spark发行版笔记4Spark Streaming事务处理彻底掌握
总体上讲是:Driver存储数据元数据信息,Executor上存储具体的数据。

Executor上存储具体的数据的具体过程如下图所示

spark发行版笔记4Spark Streaming事务处理彻底掌握

Executor 通过BlockManager写入内存+磁盘通过WAL来保证数据的安全性 (Receiver)需要注意的是:WAL仍然不能100%保证数据的安全性。当log没有积累到阈值的时候如果崩溃。

这是接收数据的角度来理解,当然Spark Streaming能工作起来,核心还是SparkContext。

Spark Streaming简单的说就俩点:一是接收数据 而是作业执行。

从数据恢复的角度来看。Spark StreamingContext可以通过checkpoint的文件系统中将元数据读进来,从而恢复数据。再通过SparkContext将作业提交给集群。

接下来在以上的基础上我们再来谈谈数据一致性的事务问题。

spark发行版笔记4Spark Streaming事务处理彻底掌握

尽管如此,数据还是有可能会数据丢失,或者数据重复处理。那么我们应该怎么办呢?

第一点:在Receiver收到数据且通过Driver调度,Executor开始计算数据时,Driver突然崩溃。将会导致Executor被kill掉,数据就会丢失,此时务必通过WAL的方式写入HDFS进行备份来保证数据安全性。(丢失的数据可以通过WAL恢复过来)

对于数据有且只被处理一次。当数据被处理后,updataOffsets执行之前如果程序突然崩溃了,就还没来得及更新offsets就很有可能导致数据重复处理(此时可以通过程序判断元数据有没有处理过,如果没有就会导致数据重复处理)

spark发行版笔记4Spark Streaming事务处理彻底掌握

当Receiver崩溃后重新启动就会通过管理Kafka的zookeeper中的元数据再次重复读取数据,但是此时的SparkStreaming认为是成功,但是kafka认为是失败的(因为没有成功执行updateOffsets)就会重复处理消费数据。

整个过程美中不足的是:性能会极大的损失

1 通过WAL的方式会极大的损失Spark Streaming中REeceiver接收数据的性能,因为要花时间先写Log,然后再写入数据。

2 如果通过kafka作为数据来源的话,kafka中有数据备份,然后通过Receiver接收数据的时候又会有副本(为数据安全性而存在的持久化备份),这个时候其实是对资源的极大的浪费。

十分幸运的是:spark 1.3的时候为解决这个性能的问题,支持了Kafka Direct API ,把kafka作为文件存储系统!!!!

减少了数据重复多余备份,又避免了WAL损耗Receiver的问题。

kafka即作为文件存储系统,又作为一个文件流,此时兼具有文件流的优势和文件系统的优势,至此之后,SparkStreaming加上Kafka就成为了相对非常完美的流处理最佳组合。

所有的Executor通过Kafka Direcit API直接消费读取数据。同时也会自己存储管理数据,自己管理自己消费。不会重复消费数据。此时就完美的解决了数据一定会处理,并且只会被处理一次。

spark发行版笔记4Spark Streaming事务处理彻底掌握

二 关于数据输出多次重写及解决方案

关于引起此问题的原因有以下几点

1  task重试

2  job重试

3 stage重试

4 慢任务推测执行

具体的解决办法是设置总共执行次数为1

1 设置spark.task.maxFailures次数为1

2 设置 spark.speculation为关闭状态,不推测执行(关闭后可以提高任务执行的效率)(少了一个步骤嘛!!!!)

3 spark streaming on kafka的话,job失败后可以设置auto.offset.reset为largest的方式。

最后再次强调:可以通过transform和foreachRDD对RDD基于业务逻辑代码进行逻辑控制来实现数据不重复消费和输出不重复。后续会具体的代码实现。敬请有兴趣的朋友们关注动态。

详细信息请查看

联系邮箱18610086859@126.com

电话:18610086859

QQ:1740415547

微信号:18610086859

整个数据设置在Driver和Executor上的分