Kafka 的数据丢失和重复消费

站酷 | 插画

本文将从消息的生产端和消息的消费端分析,数据是如何丢失的?数据是如何出现重复消费的,如何解决上述这种情况?

利用 Kafka高吞吐、可分区、可复制的特性, 在实时数据流分析应用领域,Kafka 在此大展身手。

1/生产端 Producer

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

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

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

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

官方原文:

有兴趣的读者可以去研究一下 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 等

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

  • 发表于:
  • 原文链接:https://kuaibao.qq.com/s/20181223G01V4F00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券