本期内容:
1. Exactly once容错
2. 数据输出不重复
一. 事务场景 :
以银行转帐一次为例,A用户转账给B用户,如何保证事务的一致性,即A用户能够转出且只能转出一次,B用户能够收到且只能收到一次。
二. Exactly once容错:
事务处理中如何保证能够处理且只能处理一次,数据能够输出且只能输出一次。
数据丢失的主要场景如下:
在Receiver收到数据且通过Driver的调度,Executor开始计算数据的时候如果Driver突然奔溃(导致Executor会被Kill掉),此时Executor会被Kill掉,那么Executor中的数据就会丢失。
1. 事务处理如下图 :
事务处理过程解析 :
01. InputStream : 输入数据 ;
02. Executor : 通过Receiver接收数据,当接收到数据后向Driver 汇报 ;
03. Driver : 通过StreamingContext接收到数据会启动Job进行操作 ;
2. 解决事务源数据接收的安全性 :
事务处理解析 :
01. Executor : 在Receiver接收来自Kafka数据首先通过BlockManager写入内存+磁盘或者通过WAL来保证数据的安全性;
02. Executor : 通过Replication完成后产生Ack信号;
03. Kafka : 确定收信息并读取下一条数据,Kafka才会进行updateOffsets操作 ;
04. 通过WAL机制让所有的数据通过类似HDFS的方式进行安全性容错处理,从而解决Executor被Kill掉后导致数据丢失可以通过WAL机制恢复回来。
3. 解决Driver数据输出的安全性 :
数据的处理怎么保证有且仅有被处理一次?
数据零丢失并不能保证Exactly Once,如果Receiver接收且保存起来后没来得及更新updateOffsets时,就会导致数据被重复处理。
01. 通过StreamingContext接收数据通过CheckPoint进行容错 ;
02. logging the updates : 通过记录跟踪所有生成RDD的转换(transformations)也就是记录每个RDD的lineage(血统)来重新计算生成丢失的分区数据 ;
4. Exactly Once的事务处理 :
01、 数据零丢失:必须有可靠的数据来源和可靠的Receiver,且整个应用程序的metadata必须进行checkpoint,且通过WAL来保证数据安全;
02、Spark Streaming 1.3的时候为了避免WAL的性能损失和实现Exactly Once而提供了Kafka Direct API,把Kafka作为文件存储系统!!
03、此时兼具有流的优势和文件系统的优势,Spark Streaming+Kafka就构建了完美的流处理世界!!!
04、 数据不需要copy副本,不需要WAL性能损耗,不需要Receiver,所有的Executors直接通过kafka direct api直接消费数据,直接管理Offset,所以也不会重复消费数据;
三. Spark Streaming数据输出多次重写及解决方案:
1、 为什么会有这个问题,因为SparkStreaming在计算的时候基于SparkCore,SparkCore天生会做以下事情导致SparkStreaming的结果(部分)重复输出:
1、Task重试;
2、慢任务推测;
3、Stage重复;
4、Job重试;
等会导致数据的丢失。
2、 对应的解决方案:
1、一个任务失败就是job 失败,设置spark.task.maxFailures次数为1;
2、设置spark.speculation为关闭状态(因为慢任务推测其实非常消耗性能,所以关闭后可以显著的提高Spark Streaming处理性能)
3、Spark streaming on kafka的话,假如job失败后可以设置kafka的auto.offset.reset为largest的方式会自动恢复job的执行。
最后再次强调:
可以通过transform和foreachRDD基于业务逻辑代码进行逻辑控制来实现数据不重复消费和输出不重复!这二个方法类似于spark s的后门,可以做任意想象的控制操作!