感谢DT大数据梦工厂支持提供以下内容,
DT大数据梦工厂专注于Spark发行版定制。详细信息请查看
联系邮箱18610086859@126.com
电话:18610086859
QQ:1740415547
微信号:18610086859
IMF晚8点大数据实战YY直播频道号:68917580
一 Exactly once
什么事Exactly once 事务?
数据仅被接收处理一次且只输出一次.
二 Exactly once 事务处理前提:
数据零丢失:
数据来源的零丢失:
1)有可靠的数据来源和Receiver; 2)整个应用程序的metadata必须进行checkpoint; 3)通过WAL来保证数据安全。以Kafka为例,运行在Executor上的Receiver在接收到Kafka的数据时会向Kafka发送ACK确认收到信息并读取下一条信息,kafka会updateOffset来记录Receiver接收到的偏移,这种方式保证了在Executor数据零丢失。
数据输出的零丢失:
因为spark具有高容错性,spark计算数据通过血统回溯,checkpoint等机制进行容错,数据的输出丢失可能性不大,只有一种可能app异常崩溃.
三 数据重复
数据输入的重复:
场景:在Receiver收到数据保存到HDFS等持久化引擎但是没有来得及进行updateOffsets(以Kafka为例),此时Receiver崩溃后重新启动就会通过管理Kafka的Zookeeper中元数据再次重复读取数据,但是此时SparkStreaming认为是成功的,但是kafka认为是失败的(因为没有更新offset到ZooKeeper中),此时就会导致数据重新消费的情况。
解决方式:以Receiver基于ZooKeeper的方式,当读取数据时去访问Kafka的元数据信息,在处理代码中例如foreachRDD或transform时,将信息写入到内存数据库中(memorySet),在计算时读取内存数据库信息,判断是否已处理过,如果以处理过则跳过计算。这些元数据信息可以保存到内存数据结构或者memsql,sqllite中。数据输出的重复:
场景:Spark在运行出错时不能保证输出也是事务级别的,Task执行一半的时候出错了,逻辑上据仅被处理一次,但是如果是输出到数据库中,那有可能将结果多次保存到数据库中。Spark在任务失败时会进行重试,这样会导致结果多次保存到数据库中。
解决方式:设置spark.task.maxFailures次数为1,停止Task重试。设置spark.speculation为关闭状态,关闭慢任务推测,因为慢任务推测非常消耗性能,所以关闭后可以显著提高Spark Streaming处理性能。
Spark Streaming On Kafka的话,Job失败后可以设置Kafka的参数auto.offset.reset为largest方式。
四 Kafka Direct API保证事务处理的完整性
如果通过Kafka作为数据来源,Kafka中有数据然后Receiver接收的时候又会有数据副本,这样导致存储资源的浪费。
Spark在1.3的时候为了避免WAL的性能损失和实现Exactly Once而提供了Kafka Direct API
,把Kafka作为文件存储系统。此时兼具有流的优势和文件系统的优势,至此Spark Streaming+Kafka就构建了完美的流处理世界
1. 数据不需要拷贝副本;
2. 不需要WAL,减少性能的损耗;
3. Kafka使用ZeroCopy比HDFS更高效 ;
避免重复消费数据:Executors通过Kafka Direct API直接消息数据,直接管理Offset,所以也不会重复消费数据。
另外,可以通过transform和foreachRDD基于业务逻辑进行逻辑控制来处理数据重复消费和输出重复问题。这两个方法类似于Spark Core操作底层的数据集合,也就是RDD.