2026/5/21 14:15:08
网站建设
项目流程
怎么给领导做网站分析,品牌建设及龙头企业,网站优化教程,网站建设综合训练对于高性能的消息队列来说#xff0c;在开发中消息重复与乱序是必须要考虑的问题。重复消息会引发业务逻辑的重复执行#xff0c;乱序消息则会破坏数据一致性#xff0c;直接影响系统的可靠性与稳定性。而 Kafka 作为经典的高吞吐的延迟队列#xff0c;其内置的幂等机制在开发中消息重复与乱序是必须要考虑的问题。重复消息会引发业务逻辑的重复执行乱序消息则会破坏数据一致性直接影响系统的可靠性与稳定性。而 Kafka 作为经典的高吞吐的延迟队列其内置的幂等机制正是应对这类问题的关键技术之一。本文将深入拆解 Kafka 幂等的底层逻辑希望能对大家有所帮助。出错场景消息重复假设当前 Kafka 设置的 acks 1即 Producer 发送消息后会等待 Leader 副本的响应。如果 Leader 副本所在的 Broker 节点没有返回给Producer ACK那么就会重发消息。假设当前消息已经顺利发到 Broker 中Broker 正准备返回 ACK 给 Producer。如果这时候发生网路问题ACK 在发送的过程中丢失了Producer 没有收到 ACK就会认为自己的消息没有发送成功就会再次发送同样的消息。但消息已经存在于 Broker 中了再发一次不就导致消息重复了吗消息乱序Kafka 在幂等机制的帮助下可以一次性至多发5个消息假设没有幂等那么一次性发这5个消息就会出现消息乱序的问题。不同消息发送的速率也有可能不同假设 消息A 在 消息B 发送之前但消息A的发送速率慢于 消息B消息B 就有可能先到达目标 Partition导致消息乱序。幂等原理在讲解幂等性原理之前要先考虑下面几个问题Broker 如何判断消息是否是唯一的常见的方法就是通过特殊的业务标识设置唯一键。如果设置了唯一键该以什么区分如何解决消息乱序的问题Kafka是是从分区的维度上设置唯一键的因为分布式系统下全局唯一键是不好的。同时可能存在多个Producer向同一个Partition 发送消息这多个Producer彼此发消息很难互相感知因此唯一键还要考虑上Producer。所以Kafka 的最终方案就是结合 Producer 和 TopicPartition的唯一键。同时 Producer 在发送消息的同时还会发送以 Partition 为基础的序列号从0开始随着消息的产生递增。在 Broker 端通过判断序列号是否连续来判断消息是否有序。Kafka 通过 PIDProducer ID每个Producer在初始化的时候都会分配一个 PID和 Sequence Number以TopicParititon为基础Producer在发送消息的时候会给每条消息标记一个Sequence Number来生成唯一键Producer-PID TopicPartition-SequenceNumber。Broker来存储 Sequence Number并判断如果收到的新 Sequence Number 比本地的 Sequence Number 大1说明是新消息如果相等说明是重复消息如果收到的新 Sequence Number - 本地Sequence Number 1说明消息发生了乱序具体实现Kafka 实际发送消息不是立即发送到 Broker 的而是先发送到 ProducerBatch中再以 Batch 为单位发送。Broker 通过存储一个 Map 映射来观察 TopicPartition 的状态PID, 分区状态。分区状态中最重要的属性就是batchMatadatabatchMatadata主要有五个属性lastSeq最后一个消息的序列号lastOffset最后一条消息的OffsetoffsetDelta最后一条消息和第一条消息的 Offset 差值timestamp最后一条消息的添加时间发送 ProducerBatch 的时候会以batchMatadata为根据如果新发送的Batch 和 batchMatadata 中的某个 Batch 相同说明消息重复然后直接向生产者反馈消息发送成功。还有问题未解决当 Producer 重启后它的 PID 就会发生改变幂等机制就不再成立了。因此Kafka 的幂等机制无法保证跨会话、跨分区的消息幂等。Kafka的事务机制给了解决方案这篇文章不再讨论。