定义

问题开始之前先解释下流处理中的一些概念:

  • At most once - 每条数据最多被处理一次(0次或1次)

  • At least once - 每条数据最少被处理一次 (1次或更多)

  • Exactly once - 每条数据只会被处理一次(没有数据会丢失,并且没有数据会被多次处理)

High Level API

 

如果不做容错,将会带来数据丢失
因为receiver一直在接收数据,在其没有处理的时候(已通知zk数据接收到),executor突然挂掉(或是driver挂掉通知executor关闭),缓存在其中的数据就会丢失。

因为这个问题,Spark1.2开始加入了WAL(Write ahead log)
开启 WAL,将receiver获取数据的存储级别修改为StorageLevel.MEMORY_AND_DISK_SER

val conf = new SparkConf()
conf.set("spark.streaming.receiver.writeAheadLog.enable","true")
val sc= new SparkContext(conf)
val ssc = new StreamingContext(sc,Seconds(5))
ssc.checkpoint("walDir")
val lines = KafkaUtils.createStream[String, String, StringDecoder, StringDecoder](ssc, kafkaParams, topicMap, StorageLevel.MEMORY_AND_DISK_SER).map(_._2)

开启WAL后,依旧存在数据丢失问题
即使按官方说的设置了WAL,依旧会有数据丢失,这是为什么?因为在任务中断时receiver也被强行终止了,将会造成数据丢失,提示如下:

ERROR ReceiverTracker: Deregistered receiver for stream 0: Stopped by driver
WARN BlockGenerator: Cannot stop BlockGenerator as its not in the Active state [state = StoppedAll]
WARN BatchedWriteAheadLog: BatchedWriteAheadLog Writer queue interrupted.

在Streaming程序的最后添加代码,只有在确认所有receiver都关闭的情况下才终止程序。

sys.addShutdownHook({
 ssc.stop(true,true)})

调用的方法为:

def stop(stopSparkContext: Boolean, stopGracefully: Boolean): Unit

WAL带来的问题

WAL实现的是At-least-once语义。
如果在写入到外部存储的数据还没有将offset更新到zookeeper就挂掉,这些数据将会被反复消费。同时,降低了程序的吞吐量。

Kafka Direct API

Kafka direct API 的运行方式,将不再使用receiver来读取数据,也不用使用WAL机制。

同时保证了exactly-once语义,不会在WAL中消费重复数据。不过需要自己完成将offset写入zk的过程,在官方文档中都有相应介绍。
例如如下的调用方式:

messages.foreachRDD(rdd=>{   val message = rdd.map(_._2)  //对数据进行一些操作
  message.map(method)//更新zk上的offset (自己实现)
  updateZKOffsets(rdd)
})

160728、Spark Streaming kafka 实现数据零丢失的几种方式的更多相关文章

  1. Spark Streaming使用Kafka保证数据零丢失

    来自: https://community.qingcloud.com/topic/344/spark-streaming使用kafka保证数据零丢失 spark streaming从1.2开始提供了 ...

  2. Spark Streaming消费Kafka Direct方式数据零丢失实现

    使用场景 Spark Streaming实时消费kafka数据的时候,程序停止或者Kafka节点挂掉会导致数据丢失,Spark Streaming也没有设置CheckPoint(据说比较鸡肋,虽然可以 ...

  3. 通过Spark Streaming处理交易数据

    Apache Spark 是加州大学伯克利分校的 AMPLabs 开发的开源分布式轻量级通用计算框架. 由于 Spark 基于内存设计,使得它拥有比 Hadoop 更高的性能(极端情况下可以达到 10 ...

  4. spark streaming读取kakfka数据手动维护offset

    在spark streaming读取kafka的数据中,spark streaming提供了两个接口读取kafka中的数据,分别是KafkaUtils.createDstream,KafkaUtils ...

  5. Spark Streaming + Kafka整合(Kafka broker版本0.8.2.1+)

    这篇博客是基于Spark Streaming整合Kafka-0.8.2.1官方文档. 本文主要讲解了Spark Streaming如何从Kafka接收数据.Spark Streaming从Kafka接 ...

  6. 4、spark streaming+kafka

    一.Receiver模式 1. receiver模式原理图 在SparkStreaming程序运行起来后,Executor中会有receiver tasks接收kafka推送过来的数据.数据会被持久化 ...

  7. Spark踩坑记——Spark Streaming+Kafka

    [TOC] 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark strea ...

  8. Spark Streaming+Kafka

    Spark Streaming+Kafka 前言 在WeTest舆情项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端, ...

  9. spark streaming - kafka updateStateByKey 统计用户消费金额

    场景 餐厅老板想要统计每个用户来他的店里总共消费了多少金额,我们可以使用updateStateByKey来实现 从kafka接收用户消费json数据,统计每分钟用户的消费情况,并且统计所有时间所有用户 ...

随机推荐

  1. STL容器分析--queue

    queue,顾名思义,是指队列.满足先进先出的原则.

  2. docker运行环境安装-后续步骤(二)

    1.以非 root 用户身份管理 Docker [origalom@origalom ~]$ sudo groupadd docker # 创建docker用户组[origalom@origalom ...

  3. springboot页面缓存和url缓存实例

    @Autowired RedisService redisService; @Autowired GoodsService goodsService; @Autowired ThymeleafView ...

  4. [k8s]kubelet最佳实战

    kubelet端口解析: 10250 –port: kubelet服务监听的端口,api会检测他是否存活 10248 –healthz-port: 健康检查服务的端口 10255 –read-only ...

  5. SVN提交项目时版本冲突解决方案

    版本冲突原因: 假设A.B两个用户都在版本号为7的时候,更新了index.jsp这个文件,A用户在修改完成之后提交index.jsp到服务器,这个时候提交成功,这个时候index.jsp文件的版本号已 ...

  6. oracle序列在insert into 语句中的使用

    很多人创建了序列,但是在插入语句中不知道怎么使用,在此做个简单介绍. oracle序列有两个参数:nextval和currval,使用的时候,需要输入sequence_name.nextval或seq ...

  7. 解决 Netbeans Ant: taskdef class org.netbeans.modules.java.j2seproject.copylibstask.CopyLibs cannot be found

    你在用Netbeans(实际上是Ant)Clean and Build你的项目生成可执行文件(例如Windows下的exe文件)时候遇到报错 或者遇到这样的报错: The libs.CopyLibs. ...

  8. asp.net写日志权限问题

    asp.net网站程序写不了日志,都是这个原因. 程序池的身份标识,设为内置的网络服务即可.

  9. java中for循环执行过程

    for (int j = 0; j < newSize; j++) { //执行todo } 1.首先变量j初始化为0 2.然后j=0的值跟newSize进行比较,假如为true,则执行{}里面 ...

  10. RxBinding -- 官网说明

    RxBinding -- 官网说明 新建 模板 小书匠 作用 组件 平台绑定 support-v4 绑定 appcompact-v7 绑定 design 库绑定 recyclerview-v7 绑定 ...