网易首页 > 网易号 > 正文 申请入驻

案例 | Kafka 为什么会丢消息?

0
分享至

因公众号更改推送规则,请点“在看”并加“星标”第一时间获取精彩分享

引入MQ消息中间件最直接的目的:系统解耦以及流量控制(削峰填谷)

  • 系统解耦:上下游系统之间的通信相互依赖,利用MQ消息队列可以隔离上下游环境变化带来的不稳定因素。

  • 流量控制:超高并发场景中,引入MQ可以实现流量 “削峰填谷” 的作用以及服务异步处理,不至于打崩服务。

引入MQ同样带来其他问题:数据一致性。

在分布式系统中,如果两个节点之间存在数据同步,就会带来数据一致性的问题。消息生产端发送消息到 MQ 再到消息消费端需要保证消息不丢失。

所以在使用MQ消息队列时,需要考虑这 3 个问题:

  • 如何知道有消息丢失?

  • 哪些环节可能丢消息?

  • 如何确保消息不丢失?


1、如何知道有消息丢失?

如何感知消息是否丢失了?可总结如下:

  1. 他人反馈:运营、PM反馈消息丢失。

  2. 监控报警:监控指定指标,即时报警人工调整。Kafka集群异常、Broker宕机、Broker磁盘挂载问题、消费者异常导致消息积压等都会给用户直接感觉是消息丢失了。

案例:舆情分析中数据采集同步

  • PM可自己下发采集调度指令,去采集特定数据。

  • PM可通过ES近实时查询对应数据,若没相应数据可再次下发指令。

当感知消息丢失了,那就需要一种机制来检查消息是否丢失。
检索消息

运维工具有:

  1. 查看Kafka消费位置:


# 查看某个topic的message数量$ ./kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list localhost:9092 --topic test_topic
# 查看consumer Group列表$ ./kafka-consumer-groups.sh --list --bootstrap-server 192.168.88.108:9092
# 查看 offset 消费情况$ ./kafka-consumer-groups.sh --bootstrap-server localhost:9092 --group console-consumer-1152 --describeGROUP TOPIC PARTITION CURRENT-OFFSET LOG-END-OFFSET LAG CONSUMER-ID HOST CLIENT-IDconsole-consumer-1152 test_topic 0 - 4 - consumer-console-consumer-1152-1-2703ea2b-b62d-4cfd-8950-34e8c321b942 /127.0.0.1 consumer-console-consumer-1152-1


  1. 利用工具:Kafka Tools

  1. 其他可见化界面工具

2、哪些环节可能丢消息?

一条消息从生产到消费完成经历 3 个环节:消息生产者、消息中间件、消息消费者。

哪个环节都有可能出现消息丢失问题。

1)生产端

首先要认识到Kafka生产端发送消息流程:

调用 send() 方法时,不会立刻把消息发送出去,而是缓存起来,选择恰当时机把缓存里的消息划分成一批数据,通过 Sender 线程按批次发送给服务端 Broker。

此环节丢失消息的场景有:即导致Producer消息没有发送成功

  1. 网络波动:生产者与服务端之间的链路不可达,发送超时。现象是:各端状态正常,但消费端就是没有消费消息,就像丢失消息一样。

  • 解决措施:重试props.put("retries", "10");

不恰当配置:发送消息无ack确认; 发送消息失败无回调,无日志。


producer.send(new ProducerRecord<>(topic, messageKey, messageStr),new CallBack(){...});


  • 解决措施:设置acks=1或者acks=all。发送消息设置回调。

回顾下重要的参数:acks

  • acks=0:不需要等待服务器的确认. 这是retries设置无效. 响应里来自服务端的offset总是-1producer只管发不管发送成功与否。延迟低,容易丢失数据。

  • acks=1:表示leader写入成功(但是并没有刷新到磁盘)后即向producer响应。延迟中等,一旦leader副本挂了,就会丢失数据。

  • acks=all:等待数据完成副本的复制, 等同于-1. 假如需要保证消息不丢失, 需要使用该设置. 同时需要设置unclean.leader.election.enabletrue, 保证当ISR列表为空时, 选择其他存活的副本作为新的leader.

2)服务端

先来了解下Kafka Broker写入数据的过程:

  1. Broker接收到一批数据,会先写入内存PageCacheOS Cache)中。

  2. 操作系统会隔段时间把OS Cache中数据进行刷盘,这个过程会是「异步批量刷盘」

这里就有个隐患,如果数据写入PageCacheKafka Broker宕机会怎样?机子宕机/掉电?

  • Kafka Broker宕机:消息不会丢失。因为数据已经写入PageCache,只等待操作系统刷盘即可。

  • 机子宕机/掉电:消息会丢失。因为数据仍在内存里,内存RAM掉电后就会丢失数据。

  • 解决方案:使用带蓄电池后备电源的缓存 cache,防止系统断电异常。 对比学习 MySQL 的 “双1” 策略,基本不使用这个策略,因为 “双1” 会导致频繁的 I/O 操作,也是最慢的一种。 对比学习 Redis 的 AOF 策略,默认且推荐的策略:Everysec(AOF_FSYNC_EVERYSEC) 每一秒钟保存一次(默认):。每个写命令执行完, 只是先把日志写到 AOF 文件的内存缓冲区, 每隔一秒把缓冲区中的内容写入磁盘。

拓展:Kafka日志刷盘机制

# 推荐采用默认值,即不配置该配置,交由操作系统自行决定何时落盘,以提升性能。# 针对 broker 配置:log.flush.interval.messages=10000 # 日志落盘消息条数间隔,即每接收到一定条数消息,即进行log落盘。log.flush.interval.ms=1000 # 日志落盘时间间隔,单位ms,即每隔一定时间,即进行log落盘。
# 针对 topic 配置:flush.messages.flush.ms=1000 # topic下每1s刷盘flush.messages=1 # topic下每个消息都落盘

# 查看 Linux 后台线程执行配置$ sysctl -a | grep dirtyvm.dirty_background_bytes = 0vm.dirty_background_ratio = 10 # 表示当脏页占总内存的的百分比超过这个值时,后台线程开始刷新脏页。vm.dirty_bytes = 0vm.dirty_expire_centisecs = 3000 # 表示脏数据多久会被刷新到磁盘上(30秒)。vm.dirty_ratio = 20vm.dirty_writeback_centisecs = 500 # 表示多久唤醒一次刷新脏页的后台线程(5秒)。vm.dirtytime_expire_seconds = 43200

Broker的可靠性需要依赖其多副本机制:一般副本数 3 个(配置参数:replication.factor=3

  • Leader Partition副本:提供对外读写机制。

  • Follower Partition副本:同步Leader数据。

副本之间的数据同步也可能出现问题:数据丢失问题和数据不一致问题。

解决方案:ISREpoch机制( )

  • ISR(In-Sync Replicas) :Leader宕机,可以从ISR中选择一个Follower作为Leader

  • Epoch机制:解决Leader副本高水位更新和Follower副本高水位更新在时间上是存在错配问题。

    Tips: Kafka 0.11.x 版本才引入 leader epoch 机制解决高水位机制弊端。

对应需要的配置参数如下:

  1. acks=-1或者acks=all必须所有副本均同步到消息,才能表明消息发送成功。

  2. replication.factor >= 3副本数至少有 3 个。

  3. min.insync.replicas > 1代表消息至少写入 2个副本才算发送成功。前提需要acks=-1

    举个栗子:Leader 宕机了,至少要保证 ISR 中有一个 Follower,这样这个Follwer被选举为Leader 且不会丢失数据。 公式:replication.factor = min.insync.replicas + 1
  4. unclean.leader.election.enable=false防止不在ISR中的Follower被选举为Leader

    **Kafka 0.11.0.0版本开始默认 unclean.leader.election.enable=false **

3)消费端

消费端消息丢失场景有:

  1. 消息堆积:几个分区的消息都没消费,就跟丢消息一样。

  • 解决措施:一般问题都出在消费端,尽量提高客户端的消费速度,消费逻辑另起线程进行处理。

自动提交:消费端拉下一批数据,正在处理中自动提交了offset,这时候消费端宕机了; 重启后,拉到新一批数据,而上一批数据却没处理完。

  • 解决措施:取消自动提交auto.commit = false,改为手动ack

心跳超时,引发Rebalance客户端心跳超时,触发Rebalance被踢出消费组。如果只有这一个客户端,那消息就不会被消费了。

同时避免两次 poll 的间隔时间超过阈值:
  • max.poll.records:降低该参数值,建议远远小于<单个线程每秒消费的条数> * <消费线程的个数> *的积。

  • max.poll.interval.ms: 该值要大于/ (<单个线程每秒消费的条数> * <消费线程的个数>)的值。

  • 解决措施:客户端版本升级至0.10.2以上版本。

案例:凡凡曾遇到数据同步时,消息中的文本需经过NLPNER分析,再同步到ES

这个过程的主要流程是:

  1. 数据同步程序从Kafka中拉取消息。

  2. 数据同步程序将消息内的文本发送的NER进行分析,得到特征数组。

  3. 数据同步程序将消息同步给ES

现象:线上数据同步程序运行一段时间后,消息就不消费了。

  • 排查日志:发现有Rebalance日志,怀疑是客户端消费太慢被踢出了消费组。

  • 本地测试:发现运行一段时间也会出现Rebalance,且NLPNER服务访问HTTP 500报错。

  • 得出结论:NER服务异常,导致数据同步程序消费超时。且当时客户端版本为v0.10.1Consumer没有独立线程维持心跳,而是把心跳维持与poll接口耦合在一起,从而也会造成心跳超时。

当时解决措施是:

  1. session.timeout.ms设置为25s,当时没有升级客户端版本,怕带来其他问题。

  2. 熔断机制:增加Hystrix,超过 3 次服务调用异常就熔断,保护客户端正常消费数据。

3、如何确保消息不丢失?

掌握这些技能:

  1. 熟悉消息从发送到消费的每个阶段

  2. 监控报警Kafka集群

  3. 熟悉方案 “MQ 可靠消息投递”

怎么确保消息 100% 不丢失?

到这,总结下:

  1. 生产端:

  • 设置重试:props.put("retries", "10");

  • 设置acks=all

  • 设置回调:producer.send(msg, new CallBack(){...});

  1. Broker:

  • 内存:使用带蓄电池后备电源的缓存cache

  • Kafka版本0.11.x以上:支持Epoch机制。

  • replication.factor >= 3副本数至少有 3 个。

  • min.insync.replicas > 1代表消息至少写入 2个副本才算发送成功。前提需要acks=-1

  • unclean.leader.election.enable=false防止不在ISR中的Follower被选举为Leader

  1. 消费端

  • 客户端版本升级至0.10.2以上版本。

  • 取消自动提交auto.commit = false,改为手动ack

  • 尽量提高客户端的消费速度,消费逻辑另起线程进行处理。

福利

免责声明:

本公众号部分分享的资料来自网络收集和整理,所有文字和图片版权归属于原作者所有,且仅代表作者个人观点,与本公众号无关,文章仅供读者学习交流使用,并请自行核实相关内容,如文章内容涉及侵权,请联系后台管理员删除。

特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。

Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.

相关推荐
热点推荐
奉劝所有人:退休后,跟别人关系再好,一日游、二日游都行,但千万别尝试长时间一起游,否则早晚会后悔

奉劝所有人:退休后,跟别人关系再好,一日游、二日游都行,但千万别尝试长时间一起游,否则早晚会后悔

背包旅行
2026-05-28 18:04:35
1-0大冷!中国男足以小打大赢了,等了整整7年,短短15天双杀沙特

1-0大冷!中国男足以小打大赢了,等了整整7年,短短15天双杀沙特

侃球熊弟
2026-05-31 23:03:13
首次公开电子干扰:荷兰军舰通信中断超12分钟,反制升到哪一级?

首次公开电子干扰:荷兰军舰通信中断超12分钟,反制升到哪一级?

荷兰豆爱健康
2026-05-31 12:02:55
15万!蔚来"神车"官宣:5月29日 ,正式发布亮相

15万!蔚来"神车"官宣:5月29日 ,正式发布亮相

科技堡垒
2026-05-29 11:14:19
医生:身体有这 7个表现,就是糖尿病在好转了

医生:身体有这 7个表现,就是糖尿病在好转了

医学原创故事会
2026-05-29 23:55:15
最可怕的是,一群不读书的教师在拼命教书

最可怕的是,一群不读书的教师在拼命教书

游子三月三
2026-05-23 17:43:15
全红婵做出反常决定:跳出泳池奔赴第二人生赛道,未来值得期待!

全红婵做出反常决定:跳出泳池奔赴第二人生赛道,未来值得期待!

喜欢历史的阿繁
2026-05-30 18:05:49
“指纹锁”退出中国家庭?开锁师傅说了实话,我连夜换回了铁将军

“指纹锁”退出中国家庭?开锁师傅说了实话,我连夜换回了铁将军

巢客HOME
2026-04-08 15:48:09
比开塞露还管用!这3种“推屎”食物,每天吃一点,清空宿便

比开塞露还管用!这3种“推屎”食物,每天吃一点,清空宿便

白宸侃片
2026-05-19 11:56:50
1935年,如果将泸定桥炸毁,红军可能全军覆没,刘文辉为何没炸?

1935年,如果将泸定桥炸毁,红军可能全军覆没,刘文辉为何没炸?

健康快乐丁
2025-03-29 20:30:04
央视曝光4种“致癌日用品”,家里千万别囤!很多人还被蒙在鼓里

央视曝光4种“致癌日用品”,家里千万别囤!很多人还被蒙在鼓里

39健康网
2026-05-27 10:32:46
99年我回村葬母无人搭理,只有1户人家热心帮忙,15年后我去报恩

99年我回村葬母无人搭理,只有1户人家热心帮忙,15年后我去报恩

千秋文化
2025-09-05 11:30:00
沈阳开始“收房子了”,二环以内建面70㎡以下房源可参与!

沈阳开始“收房子了”,二环以内建面70㎡以下房源可参与!

栋察楼市
2026-05-31 13:30:36
别墅搜出23件国宝,全家集体失联!整整17年,徐湖平案终于落幕

别墅搜出23件国宝,全家集体失联!整整17年,徐湖平案终于落幕

鉴史录
2026-05-31 12:57:55
一夜之间肺白了!高烧3天,头孢也没用……紧急提醒:已有多人中招

一夜之间肺白了!高烧3天,头孢也没用……紧急提醒:已有多人中招

环球网资讯
2026-05-28 11:45:03
“只要大陆敢打,我就敢送”,他公开宣称

“只要大陆敢打,我就敢送”,他公开宣称

安安说
2026-05-24 15:20:17
安切洛蒂正在用事实阐明他被巴西国家队聘用的原因

安切洛蒂正在用事实阐明他被巴西国家队聘用的原因

工从昊懂球阿靖
2026-06-01 00:34:22
武汉知名男演员庆祝结婚10周年,胡歌、彭于晏当年是伴郎

武汉知名男演员庆祝结婚10周年,胡歌、彭于晏当年是伴郎

扬子晚报
2026-05-30 20:00:01
活久见!绍兴一则保安征婚,要求女方每月给一万元零花钱,引热议

活久见!绍兴一则保安征婚,要求女方每月给一万元零花钱,引热议

火山詩话
2026-05-31 10:00:24
罗马诺:曼联非常喜欢楚阿梅尼,但薪水和转会费都是问题

罗马诺:曼联非常喜欢楚阿梅尼,但薪水和转会费都是问题

懂球帝
2026-06-01 04:13:07
2026-06-01 04:28:49
IT架构师联盟 incentive-icons
IT架构师联盟
IT架构实战分享
842文章数 7672关注度
往期回顾 全部

科技要闻

戴尔诺基亚又回来了!AI重估老牌科技公司

头条要闻

特朗普生日白宫办格斗赛 近距离观赛花超100万美元

头条要闻

特朗普生日白宫办格斗赛 近距离观赛花超100万美元

体育要闻

阿森纳用最悲壮的方式,成就了巴黎王朝

娱乐要闻

朱军退休,正义虽迟但到,女方受惩

财经要闻

医学首席转岗搞科技,A股科技股遭遇巨震

汽车要闻

900V+3.2秒破百 领克10+&领克10上市16.99万元起

态度原创

教育
房产
旅游
时尚
游戏

教育要闻

(序号A49205)校园安全教育责任与担当主题班会PPT..

房产要闻

红动五月!全国抢入核心资产,广州盯紧凯旋新世界!

旅游要闻

半马苏河秀迎来“青春版”升级!校地联动解锁文商旅体展融合新玩法

梓渝:慢下来,也很好

《巫师3》资料片“血与酒”发售十周年 纪念贺图发布

无障碍浏览 进入关怀版