/* 王家林老师授课http://weibo.com/ilovepains 每天晚上20:00YY频道现场授课频道68917580*/
Exactly Once的事务处理:
1,数据零丢失:必须有可靠的数据来源和可靠的Receiver,且整个应用程序的metadata必须进行checkpoint,且通过WAL来保证数据安全;
2,Spark Streaming 1.3的时候为了避免WAL的性能损失和实现Exactly Once而提供了Kafka Direct API,把Kafka作为文件存储系统!!!此时兼具有流的优势和文件系统的优势,至此,Spark Streaming+Kafka就构建了完美的流处理世界!!!所有的Executors通过Kafka API直接消费数据,直接管理Offset,所以也不会重复消费数据;事务实现啦!!!
数据丢失及其具体的解决方式:
在Receiver收到数据且通过Driver的调度Executor开始计算数据的时候如果Driver突然崩溃,则此时Executor会被Kill掉,那么Executor中的数据就会丢失,此时就必须通过例如WAL的方式让所有的数据都通过例如HDFS的方式首先进行安全性容错处理,此时如果Executor中的数据丢失的话就可以通过WAL恢复回来;
通过WAL方式会极大的损伤Spark Streaming中Receivers接受数据的性能;
数据重复读取的情况:
在Receiver收到数据且保存到了HDFS等持久化引擎但是没有来得及进行updateOffsets,此时Receiver崩溃后重新启动就会通过管理Kafka的ZooKeeper中元数据再次重复读取数据,但是此时SparkStreaming认为是成功的,但是Kafka认为是失败的(因为没有更新offset到ZooKeeper中),此时就会导致数据重新消费的情况。
性能损失:
1,通过WAL方式会极大的损伤Spark Streaming中Receivers接受数据的性能;
2,如果通过Kafka的作为数据来源的话,Kafka中有数据,然后Receiver接受的时候又会有数据副本,这个时候其实是存储资源的浪费;
关于Spark Streaming数据输出多次重写及其解决方案:
1,为什么会有这个问题,因为Spark Streaming在计算的时候基于Spark Core,Spark Core天生会做以下事情导致Spark Streaming的结果(部分)重复输出:
Task重试;
慢任务推测
Stage重复;
Job重试;
2,具体解决方案:
设置spark.task.maxFailures次数为1;
设置spark.speculation为关闭状态(因为慢任务推测其实非常消耗性能,所以关闭后可以显著提高Spark Streaming处理性能)
Spark Streaming on Kafka的话,Job失败后可以设置auto.offset.reset为“largest”的方式;
最后再次强调可以通过transform和foreachRDD基于业务逻辑代码进行逻辑控制来实现数据不重复消费和输出不重复!这两个方式类似于Spark Streaming的后门,可以做任意想象的控制操作!