那么 Kafka 到底会不会丢数据呢?如果丢数据,究竟该怎么解决呢?
只有掌握了这些, 我们才能处理好 Kafka 生产级的一些故障,从而更稳定地服务业务 。
认真读完这篇文章,我相信你会对Kafka 如何解决丢数据问题,有更加深刻的理解 。
文章插图
一、总体概述
越来越多的互联网公司使用消息队列来支撑自己的核心业务 。由于是核心业务,一般都会要求消息传递过程中最大限度做到不丢失,如果中间环节出现数据丢失,就会引来用户的投诉,年底绩效就要背锅了 。
那么使用 Kafka 到底会不会丢数据呢?如果丢数据了该怎么解决呢?为了避免类似情况发生,除了要做好补偿措施,我们更应该在系统设计的时候充分考虑系统中的各种异常情况,从而设计出一个稳定可靠的消息系统 。
大家都知道 Kafka 的整个架构非常简洁,是分布式的架构,主要由 Producer、Broker、Consumer 三部分组成,后面剖析丢失场景会从这三部分入手来剖析 。
文章插图
二、消息传递语义剖析
在深度剖析消息丢失场景之前,我们先来聊聊「消息传递语义」到底是个什么玩意?
所谓的消息传递语义是 Kafka 提供的 Producer 和 Consumer 之间的消息传递过程中消息传递的保证性 。主要分为三种, 如下图所示:
文章插图
- 首先当 Producer 向 Broker 发送数据后,会进行 commit,如果 commit 成功,由于 Replica 副本机制的存在,则意味着消息不会丢失,但是 Producer 发送数据给 Broker 后,遇到网络问题而造成通信中断,那么 Producer 就无法准确判断该消息是否已经被提交(commit),这就可能造成 at least once 语义 。
- 在 Kafka 0.11.0.0 之前, 如果 Producer 没有收到消息 commit 的响应结果,它只能重新发送消息,确保消息已经被正确的传输到 Broker,重新发送的时候会将消息再次写入日志中;而在 0.11.0.0 版本之后, Producer 支持幂等传递选项,保证重新发送不会导致消息在日志出现重复 。为了实现这个, Broker 为 Producer 分配了一个ID,并通过每条消息的序列号进行去重 。也支持了类似事务语义来保证将消息发送到多个 Topic 分区中,保证所有消息要么都写入成功,要么都失败,这个主要用在 Topic 之间的 exactly once 语义 。
启用事务支持的方法配置:设置属性 transcational.id = "指定值" 。
- 从 Consumer 角度来剖析, 我们知道 Offset 是由 Consumer 自己来维护的, 如果 Consumer 收到消息后更新 Offset, 这时 Consumer 异常 crash 掉, 那么新的 Consumer 接管后再次重启消费,就会造成 at most once 语义(消息会丢,但不重复) 。
- 如果 Consumer 消费消息完成后, 再更新 Offset, 如果这时 Consumer crash 掉,那么新的 Consumer 接管后重新用这个 Offset 拉取消息, 这时就会造成 at least once 语义(消息不丢,但被多次重复处理) 。
从 Kafka 整体架构图我们可以得出有三次消息传递的过程:
- Producer 端发送消息给 Kafka Broker 端 。
- Kafka Broker 将消息进行同步并持久化数据 。
- Consumer 端从 Kafka Broker 将消息拉取并进行消费 。
通过上面三步,我们可以得出:Kafka 只对 「已提交」的消息做「最大限度的持久化保证不丢失」 。
怎么理解上面这句话呢?
- 首先是 「已提交」的消息,当 Kafka 中 N 个 Broker 成功收到一条消息并写入到日志文件后,它们会告诉 Producer 端这条消息已成功提交了,那么这时该消息在 Kafka 中就变成 "已提交消息" 了 。
推荐阅读
- 宋祖儿真面目曝光!从小为上位不择手段,她的私生活到底有多乱?
- 邓为的塌方会不会给《长相思》带来负面影响
- 陈惠敏:揭露刘嘉玲、蓝洁瑛当年事件真相,李小龙到底被何人所害
- 杨丽萍身体秘密被曝光,难怪公共场合10年不摘帽子,到底隐藏什么?
- 软水到底能不能喝 软水到底能不能喝呀
- 臭氧到底是什么东西 臭氧是一种什么东西
- “一代女神”滕丽名,47岁已如此苍老,她到底经历了什么?
- 电蚊香液一直开不关,会不会爆炸 电蚊香液一直插着不关的危害
- 到底该不该使用Python?
- 4年拼3胎,豪门女下嫁大22岁男星,她到底在图啥?