Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >注意:Kafka 的这 6 个场景会丢失消息!

注意:Kafka 的这 6 个场景会丢失消息!

作者头像
jinjunzhu
发布于 2024-04-12 08:05:12
发布于 2024-04-12 08:05:12
17101
代码可运行
举报
文章被收录于专栏:个人开发个人开发
运行总次数:1
代码可运行

大家好,我是君哥。

我们使用 Kafka 的时候,怎样能保证不丢失消息呢?今天来聊一聊这个话题。

首先我们看一下 Kafka 的架构图,

场景一:异步发送

Producer 异步发送是丢失消息比较多的场景,Kafka 异步发送的代码如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ProducerRecord<byte[],byte[]> record = new ProducerRecord<byte[],byte[]>("the-topic", key, value);
RecordMetadata metadata = producer.send(record).get();

Producer 发送消息后,不用等待发送结果,就可以继续执行后面的逻辑。如果发送失败,就会丢失消息。

Kafka 提供了回调方法,可以同步等待发送结果,这样降低了发送效率,但可以对发送失败的场景进行处理,比如重新发送。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
ProducerRecord<byte[],byte[]> record = new ProducerRecord<byte[],byte[]>("the-topic", key, value);
producer.send(record,
                (Callback) (metadata, e) -> {
                    if(e != null) {
                        e.printStackTrace();
                    } else {
                        System.out.println("The offset of the record we just sent is: " + metadata.offset());
                    }
                });

场景二:配置 acks=0

从文章开头的架构图中可以看到,Broker Leader 节点收到消息后,会同步给 Follower 节点。

在 Producer 端有一个 acks 配置,说明如下 :

  • acks=0:Producer 发送消息后不等待 Broker 的响应;
  • acks=1:Producer 发送消息后,Leader 节点写入消息成功后给 Producer 发送响应;
  • acks=all/-1:Producer 发送消息后,需要 ISR 列表中所有 Broker 节点都写入消息成功才会给 Producer 发送响应。

注意:acks=all/-1 是最高安全级别,可以配合 min.insync.replicas 参数使用,当 acks=all/-1 时,min.insync.replicas 表示 ISR 列表中最小写入消息成功的副本数。

如下图,cks=all/-1,当 min.insync.replicas=2 时,

如果 ISR 列表中有【Broker0、Broker1】,即使 Broker2 写入消息失败,也会给 Producer 返回成功。

如果 ISR 列表中只有【Broker0】,则无论如何都不会给 Producer 返回成功。

如果 ISR 列表中有【Broker0、Broker1、Broker2】,则 3 个 Broker 都写成功才会给 Producer 返回成功。

场景三:发送端重试

如果配置 retries=0,Producer 发送消息失败后是不会进行重试的,要保证消息不丢失,可以增加 retries 的配置值,避免因为网络抖动而造成的发送失败。

场景四:Follower 落后太多

Kafka Broker 有一个参数:unclean.leader.election.enable,这个参数值说明如下:

  • true:允许 ISR 列表之外的节点参与竞选 Leader;
  • false:不允许 ISR 列表之外的节点参与竞选 Leader。

如果设置为 true,也是会丢失消息的,看下图:

如果 Leader 和 Follower1 都挂了,这时就要考虑是否让 Follower2 参加竞选,把 unclean.leader.election.enable 参数值设置为 true,则 Follower2 也可以竞选 Leader,并且作为唯一存活节点成功竞选为 Leader,但是它并没有同步到偏移量为 3、4、5 的消息,

而之前的 Leader 上线后,成为了 Follower,因为 Follower 的 LEO(Log End Offset)不能大于 Leader,所以之前偏移量为 3、4、5 的消息就被丢弃了。如下图:

所以,要保证消息不丢失,unclean.leader.election.enable 这个参数值要设置为 false。

场景五:Broker 宕机

为了提升性能,Kafka 使用 Page Cache,先将消息写入 Page Cache,采用了异步刷盘机制去把消息保存到磁盘。如果刷盘之前,Broker Leader 节点宕机了,并且没有 Follower 节点可以切换成 Leader,则 Leader 重启后这部分未刷盘的消息就会丢失。

这种场景下多设置副本数是一个好的选择,通常的做法是设置 replication.factor >= 3,这样每个 Partition 就会有 3 个以上 Broker 副本来保存消息,同时宕机的概率很低。

同时可以配合场景二中的参数 min.insync.replicas > 1(不建议使用默认值 1),表示消息至少要被成功写入到 2 个 Broker 副本才算是发送成功。

注意:参数配置要保证 replication.factor > min.insync.replicas,通常设置成 replication.factor = min.insync.replicas + 1。如果这 2 个参数设置成相等,则只要有一个 Broker 节点宕机,Broker 就无法给 Producer 返回发送成功,系统可用性降低。

场景六:并发消费

如果消费端采用多线程并发消费,很容易因为并发更新 Offset 导致消费失败。看下图:

线程 1 拉取 3 条消息把 Offset 更新成 3,线程 2 把 Offset 更新成 6,线程 3 把 Offset 更新成 9。这时如果线程 2 消费失败了,想要重新消费,但是 Offset 已经更新到了 9,不能拉取到 Offset 9 以前的消息了。

所以,消费者并发消费很可能会造成消息丢失,如果对消息丢失很敏感,最好使用单线程来进行消费。

如果采用多线程,可以把 enable.auto.commit 设置为 false,这样相当于每次消费完后手动更新 Offset。不过这又会带来重复消费问题,比如上面的例子,如果线程 2 消费失败了,则手动把 Offset 更新成 3,线程 3 消费成功后,再次拉取,还会拉取到 6、7、8 这三条数据。因此消费端需要做好幂等处理。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2024-04-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 君哥聊技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Kafka —— 如何保证消息不会丢失
当我们通过 send(msg, callback) 是不是就意味着消息一定不丢失了呢?
solve
2019/11/26
1.5K0
一文理解Kafka如何消息不丢失
本文只聚焦于Kafka系统的消息丢失,如果是生产环境出现数据丢失,排查时要先从链路上分段定位,缩小问题范围。
全菜工程师小辉
2021/06/25
1.6K0
Kafka 数据可靠性深度解读
1 概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用。目前越来越多的开源分布式处理系统如Cloudera、Apache Storm、Spark等都支持与Kafka集成。 Kafka凭借着自身的优势,越来越受到互联网企业的青睐,唯品会也采用Kafka作为其内部核心消息引擎之一。Kafka作为一个商业级消息中间件,消息可靠性的重要性可想而知。如何确保消息的精确传输?如何确保消息的准确存储?如何确保消息的正
用户1263954
2018/01/30
1.5K0
Kafka 数据可靠性深度解读
Kafka消息分区&producer拦截器&无消息丢失(八)
上篇文章说了,acks,1代表什么都不管,即使配置了回调也不会起作用,0代表不会等待replic副本里的不会持久化,只要broker leader持久化成功则返回给producer。-1代表all,则表示全部持久化成功才返回成功给producer,Retries,batch.size:kafka,linger.ms,buffer.memory,compression.type等参数。
用户9919783
2022/12/14
3950
Kafka零数据丢失的配置方案
如果要想保证Kafka数据不丢, 要从Kafka的三个地方入手:生产者、服务端和消费者。
江帅帅
2020/05/15
9650
kafka是如何保证消息不丢失的
今天和大家聊一下,kafka对于消息的可靠性保证。作为消息引擎组件,保证消息不丢失,是非常重要的。
一条老狗
2020/02/24
12.1K0
案例 | Kafka 为什么会丢消息?
点击上方“芋道源码”,选择“设为星标” 管她前浪,还是后浪? 能浪的浪,才是好浪! 每天 10:33 更新文章,每天掉亿点点头发... 源码精品专栏 原创 | Java 2021 超神之路,很肝~ 中文详细注释的开源项目 RPC 框架 Dubbo 源码解析 网络应用框架 Netty 源码解析 消息中间件 RocketMQ 源码解析 数据库中间件 Sharding-JDBC 和 MyCAT 源码解析 作业调度中间件 Elastic-Job 源码解析 分布式事务中间件 TCC-Transaction
芋道源码
2022/09/14
8690
案例 | Kafka 为什么会丢消息?
面试官问我如何保证Kafka不丢失消息?我哭了!
不了解 Kafka 的朋友建议先看一看我的下面这几篇文章,第一篇一定要看,其他的可以按需学习。
Guide哥
2020/05/07
2.9K0
面试官问我如何保证Kafka不丢失消息?我哭了!
kafka参数使用
客户端先将消息写入内存缓存, 多个消息形成一个个Batch, 然后send线程将多个Batch打包成一个request发送到kafka服务器上。
leobhao
2022/06/28
6090
kafka参数使用
硬核 | Kafka 如何解决消息不丢失?
Kafka 消息框架,大家一定不陌生,很多人工作中都有接触。它的核心思路,通过一个高性能的MQ服务来连接生产和消费两个系统,达到系统间的解耦,有很强的扩展性。
捡田螺的小男孩
2021/08/12
8700
硬核 |  Kafka 如何解决消息不丢失?
Kafka笔记—可靠性、幂等性和事务
这几天很忙,但是我现在给我的要求是一周至少要出一篇文章,所以先拿这篇笔记来做开胃菜,源码分析估计明后两天应该能写一篇。给自己加油~,即使没什么人看。
luozhiyun
2019/09/10
1.1K0
面试系列-kafka高可用机制
Kafka允许同⼀个Partition存在多个消息副本(Replica),每个Partition的副本通常由1个Leader及0个以上的Follower组成,⽣产者将 消息直接发往对应Partition的Leader,Follower会周期地向Leader发送同步请求,Kafka的Leader机制在保障数据⼀致性地同时降低了了 消息备份的复杂度; 同⼀Partition的Replica不应存储在同一个Broker上,因为一旦该Broker宕机,对应Partition的所有Replica都无法⼯作,这就达不到 高可用的效果。为了做好负载均衡并提⾼容错能力,Kafka会尽量将所有的Partition以及各Partition的副本均匀地分配到整个集群上;
用户4283147
2022/12/29
5330
面试系列-kafka高可用机制
kafka学习
Apache Kafka是由LinkedIn采用Scala和Java开发的开源流处理(open source、 stream-processing)平台,该项目旨在提供统一的、高吞吐量、低延迟的平台来处理实时数据流。
艾利
2022/08/16
4070
Kafka 消息丢失与消费精确一次性
如果Kafka Producer使用“发后即忘”的方式发送消息,即调用producer.send(msg)方法来发送消息,方法会立即返回,但此时并不能说明消息已经发送成功。消息发送方式详见初次邂逅Kafka生产者。
江帅帅
2020/07/03
7510
Kafka技术知识总结之五——Kafka的高可用性
Kafka 实现高可用性的方式是进行 replication。对于 kafka,如果没有提供高可用性机制,一旦一个或多个 Broker 宕机,则宕机期间其上所有 Partition 都无法继续提供服务。若该 Broker永远不能再恢复,那么所有的数据也就将丢失,这是不可容忍的。所以 kafka 高可用性的设计也是进行 Replication。 Replica 的分布:为了尽量做好负载均衡和容错能力,需要将同一个 Partition 的 Replica 尽量分散到不同的机器。 Replica 的同步:当有很多 Replica 的时候,一般来说,对于这种情况有两个处理方法:
剑影啸清寒
2020/07/08
1.3K0
简单理解 Kafka 的消息可靠性策略
作者:hymanzhang,腾讯 IEG 运营开发工程师 背景 部门的开发同学最近在开发一个活动的过程中,需要关注大量的应用后台逻辑,捕捉各种事件的触发。在设计时打算采用 kafka 消息队列进行业务逻辑的解耦,这样活动开发和后台开发同学的工作就分离开了。但是使用的同学不是很熟悉其原理,担心以下几个问题: 我什么业务场景下使用消息队列 我发消息的时候,需要等 ack 嘛 我发了消息之后,消费者一定会收到嘛? 申请腾讯云的 kafka 实例后,各种参数怎么设置呀? 遇到各种故障时,我的消息会不会丢?
腾讯技术工程官方号
2020/11/25
2.8K0
Kafka 的稳定性
多分区原子写入: 事务能够保证Kafka topic下每个分区的原⼦写⼊。事务中所有的消息都将被成功写⼊或者丢弃。 ⾸先,我们来考虑⼀下原⼦读取-处理-写⼊周期是什么意思。简⽽⾔之,这意味着如果某个应⽤程序在某个topic tp0的偏移量X处读取到了消息A,并且在对消息A进⾏了⼀些处理(如B = F(A)),之后将消息B写⼊topic tp1,则只有当消息A和B被认为被成功地消费并⼀起发布,或者完全不发布时,整个读取过程写⼊操作是原⼦的。 现在,只有当消息A的偏移量X被标记为已消费,消息A才从topic tp0消费,消费到的数据偏移量(record offset)将被标记为提交偏移量(Committing offset)。在Kafka中,我们通过写⼊⼀个名为offsets topic的内部Kafka topic来记录offset commit。消息仅在其offset被提交给offsets topic时才被认为成功消费。 由于offset commit只是对Kafka topic的另⼀次写⼊,并且由于消息仅在提交偏移量时被视为成功消费,所以跨多个主题和分区的原⼦写⼊也启⽤原⼦读取-处理-写⼊循环:提交偏移量X到offset topic和消息B到tp1的写⼊将是单个事务的⼀部分,所以整个步骤都是原⼦的。
用户7353950
2022/06/23
1.3K0
Kafka 的稳定性
Kafka 是如何保证数据可靠性和一致性
学过大数据的同学应该都知道 Kafka,它是分布式消息订阅系统,有非常好的横向扩展性,可实时存储海量数据,是流数据处理中间件的事实标准。本文将介绍 Kafka 是如何保证数据可靠性和一致性的。
大数据技术架构
2019/08/16
6.7K0
Kafka 是如何保证数据可靠性和一致性
【大数据哔哔集20210124】有人问我Kafka Leader选举?我真没慌
一条消息只有被ISR中所有Follower都从Leader复制过去才会被认为已提交。这样就避免了部分数据被写进了Leader,还没来得及被任何Follower复制就宕机了,而造成数据丢失。而对于Producer而言,它可以选择是否等待消息commit,这可以通过request.required.acks来设置。这种机制确保了只要ISR中有一个或者以上的follower,一条被commit的消息就不会丢失。
大数据真好玩
2021/02/23
3360
【大数据哔哔集20210124】有人问我Kafka Leader选举?我真没慌
面试题:Kafka 如何保证高可用?有图有真相!
Kafka从0.8版本开始提供了高可用机制,可保障一个或多个Broker宕机后,其他Broker能继续提供服务
张乘辉
2021/06/10
1.2K0
面试题:Kafka 如何保证高可用?有图有真相!
相关推荐
Kafka —— 如何保证消息不会丢失
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验