Spark版本定制第4天:Exactly Once的事务处理
本期内容:
1 Exactly once 容错
2 数据输出不重复
一切不能进行实时流处理的数据都是无效的数据。在流处理时代,SparkStreaming有着强大吸引力,而且发展前景广阔,加之Spark的生态系统,Streaming可以方便调用其他的诸如SQL,MLlib等强大框架,它必将一统天下。
Spark Streaming运行时与其说是Spark Core上的一个流式处理框架,不如说是Spark Core上的一个最复杂的应用程序。如果可以掌握Spark streaming这个复杂的应用程序,那么其他的再复杂的应用程序都不在话下了。这里选择Spark Streaming作为版本定制的切入点也是大势所趋。
我们都知道事务处理中如何保证能够处理且只能处理一次,数据能够输出且只能输出一次这点至关重要。那么Spark如何保证这一点呢,本节将讨论具体的可能出现问题的场景,并提供解决方案
一:Exactly once
1事务处理的数据源安全性
从Executor出发,当Receiver接收来自Kafka数据首先通过BlockManager写入内存(或者磁盘)或者通过WAL来保证数据的安全性,同时Executor会通过Replication完成后产生Ack信号;
从Kafka出发,当确定收信息并读取下一条数据,Kafka才会进行updateOffsets操作 ;
从WAL机制出发,WAL机制会让所有的数据通过类似HDFS的方式进行安全性容错处理,从而解决Executor挂掉导致的数据丢失
2事务处理完的输出安全性
从上图看出,解决Driver端数据输出安全性主要是两点:
一是基于checkpoint的容错
二是基于lineage(血统)的容错
3 Spark Exactly的事务处理
鉴于以上两点,我们知道了要想保证数据零丢失,必须有可靠的数据来源和可靠的数据接受这,且整个应用程序必须进行checkpoint,且需通过WAL来保证数据安全。为此次Spark Streaming的为了避免WAL的性能损失和实现Exactly Once而提供了Kafka Direct API,把Kafka作为文件存储系统,这么做兼具有流式处理的优势和文件系统的优势,所有的Executors直接通过kafka Direct Api直接消费数据,直接管理Offset,不会消耗性能也不会重复消费数据。
二:数据输出不重复
输出不重复也是生产环境中的重要问题。
1 产生数据重复输出的原因?
Task重试
慢任务推测
Stage重复
Job重试
2 解决方案
2.1 关于Job,Stage和Task的重试问题,一个任务失败就是job的 失败,我们可以设置spark.task.maxFailures次数为1;
2.2 设置spark.speculation为关闭慢任务推测状态
2.3 如果Spark Streamingk是结合kafka的话,job失败后可以设置kafka的auto.offset.reset为largest。
最后总结
可以通过transform和foreachRDD基于业务逻辑代码进行逻辑控制来实现数据不重复消费和输出不重复!这二个方法类似于Spark Streaming的后门,可以做任意想象的控制操作!