Kafka 的数据丢失和重复消费

1/ 生产端 Producer

 

消息格式:每个消息是一个 ProducerRecord 对象,必须指定消息所属的 Topic 和消息值 Value ,此外还可以指定消息所属的 Partition 以及消息的 Key。Producer 生产数据默认是先写到内存(PageCache)中的,定期 flush 到磁盘上。默认的这个参数是:

 

 

 

 

设置较小定期 flush 的时间,并不能真正保证数据不会丢失。通过查看官方提供的默认配置 Long.MaxValue 也可以看出,官方是不建议我们通过这个参数来改变什么的,也就是说设置 flush 的时间,不能从根本上保证我们的数据丢失问题。

 

前面一开始提到,kafka 作为一个可分区和可复制的消息队列。我们可以利用它的分区副本机制,为每一个 Topic 的数据分为多个分区,每个分区放在不同的节点上,每个分区默认只有一分数据,通过设置参数 --replication-factor 2 ,可以执行每个分区有三份数据,其中有两份是用来备份的。

 

分区有副本了,也会存在 leader 和 follower 的角色,zookeeper 中维护了一个 ISR 列表。

 

这时,生产者往 broker 中写入数据的时候,默认的消息确认级别是 request.required.acks = 0, 表示生产者发送消息之后,不会等待 leader的确认。

 

 

所以,需要把这个设置为 -1 ,表示生产者发送消息要等到 leader 以及所有的副本都同步了,才会返回确认消息。当然,这种方案也不是非常万无一失的,官方提出的建议是,还需要配置 min.insync.replicas 最小同步的副本数,如果没有得到这个最小数的要求,生产者会抛出异常,本次写入不会成功。比如,我有三个副本,那么最好找个参数要设置成 2 ,要保证大部分的副本同步了数据。

 

官方原文:

 

 

 

 

 

总结:request.required.acks = -1 虽然保证了数据的一致性,但是同时也影响了性能。在实际业务中应该考虑数据少量丢失对于业务的影响,要根据自己的情况来,结合业务来平衡数据一致性和系统的性能。

 

有兴趣的读者可以去研究一下 CAP, 分布式系统的三个指标,推荐阮一峰老师写的 -- CAP 定义的原理。

 

2/ 消费端 Consumer

 

消费端数据丢失的原因是 offset 的自动提交。

 

 

 

 

由于在使用kafka的高级API时,消费者会自动每隔一段时间将offset保存到zookeeper上,此时如果刚好将偏移量提交到zookeeper上后,但这条数据还没消费完,机器发生宕机,此时数据就丢失了。

 

解决方法:关闭自动提交,改成手动提交,每次数据处理完后,再提交。

 

数据重复消费,在消费者自动提交offset到zookeeper后,程序又消费了几条数据,但是还没有到下次自动提交offset到zookeeper之时,如果机器宕机了,然后重启,此时消费者会去读zookeeper上的偏移量进行消费,这就会导致数据重复消费。 解决方法:关闭自动提交,改成手动提交。

 

这里再提一下 kafka 的两种方式API,以供大家选择合适的。

 

高级 API 的特点

 

优点

● 高级API写起来简单

● 不需要去自行去管理offset,系统通过zookeeper自行管理

● 不需要管理分区,副本等情况,系统自动管理

● 消费者断线会自动根据上一次记录在 zookeeper中的offset去接着获取数据

缺点

● 不能自行控制 offset(对于某些特殊需求来说)

● 不能细化控制如分区、副本、zk 等

 

低级 API 的特点

 

优点

● 能够开发者自己控制offset,想从哪里读取就从哪里读取。

● 自行控制连接分区,对分区自定义进行负载均衡

● 对 zookeeper 的依赖性降低(如:offset 不一定非要靠 zk 存储,自行存储offset 即可,比如存在文件或者内存中)

缺点

● 太过复杂,需要自行控制 offset,连接哪个分区,找到分区 leader 等

 

本文就到这里,实际生产中需要结合自己的业务去选择。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值