该如何保证消息不被重复消费

简介: 该如何保证消息不被重复消费

前言

回答这个问题,首先别听到重复消息这个问题就一无所知。先大概说一说可能会有哪些重复消费的问题

首先,比如 RabbitMQRocketMQKafka,都有可能会出现消息重复消费的问题。

因为这问题通常不是 MQ 自己保证的,是由开发来保证的。挑一个 Kafka 来举个例子,说说怎么重复消费。

Kafka 实际上有个 offset 的概念,就是每个消息写进去,都有一个 offset,代表消息的序号。

然后 consumer 消费了数据之后,每隔一段时间(定时定期),会把自己消费过的消息的 offset提交一下,表示:我已经消费过了,下次我要是重启或宕机的,就让我继续从上次消费到的 offset来继续消费吧

但是凡事总有意外,比如我们之前生产经常遇到的,如果着急直接 kill 进程了再重启。这会导致 consumer有些消息处理了,但是没来得及提交 offset。重启之后,少数消息会再次消费一次。

重复消费的出现

当前假设场景:

数据 1/2/3 依次进入 KafkaKafka 会给这三条数据每条分配一个 offset,代表这条数据的序号。

假设分配的 offset依次是 152/153/154。消费者从 Kafka 去消费的时候,也是按照这个顺序去消费。假如当消费者消费了 offset=153 的这条数据,刚准备去提交offsetZookeeper,此时消费者进程被重启了。

那么此时消费过的数据 1/2 的offset并没有提交,Kafka 也就不知道你已经消费了 offset=153 这条数据。那么重启之后,消费者会让 Kafka上次消费到的地方后面的数据继续传递过来。

由于之前的 offset 没有提交成功,那么数据 1/2 会再次传过来,如果此时消费者没有去重的话,那么就会导致重复消费。

新版的 Kafka 已经将 offset 的存储从 Zookeeper 转移至 Kafka brokers,并使用内部位移主题 __consumer_offsets 进行存储。

image.png

如果消费者是拿一条数据就往数据库里写一条,会导致把数据 1/2 在数据库里插入了 2 次,那么数据就出错啦。

其实重复消费不可怕,可怕的是没考虑到重复消费之后,怎么保证幂等性

消息消费的幂等性

幂等性,通俗点说,就一个数据,或者一个请求,重复来多次,确保对应的数据是不会改变的,不能出错

举个例子。

假设当前有个系统,消费一条消息就往数据库里插入一条数据,如果一个消息重复两次,就相当于插入了两条,数据就错了。

但是你要是消费到第二次的时候,自己判断一下是否已经消费过了,若是就直接扔了,这样就保留了一条数据,从而保证了数据的正确性

一条数据重复出现两次,数据库里就只有一条数据,这就保证了系统的幂等性。

如何保证消息队列消费的幂等性

还得结合业务来思考,下面有几个处理思路:

  • 比如拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下
  • 比如是写 Redis,也不存在需要保证,反正每次都是 set,天然幂等性。
  • 比如不是上面两个场景,做得稍微复杂一点
    需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类,然后消费到了之后,先根据这个 idRedis 里查一下是否消费过,如果没有消费过,就处理,然后这个idRedis。如果消费过了,那就别处理了,保证别重复处理相同的消息即可。
  • 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。

image.png


目录
相关文章
|
6月前
|
消息中间件 NoSQL Kafka
如何保证消息不被重复消费~~~~~(如何保证消息队列的幂等性)
如何保证消息不被重复消费~~~~~(如何保证消息队列的幂等性)
|
消息中间件 缓存 NoSQL
如何实现消费幂等 ?
这篇文章,我们聊聊消息队列中非常重要的最佳实践之一:**消费幂等**。
如何实现消费幂等 ?
|
消息中间件 存储 Kafka
MQ保证消息幂等机制
MQ保证消息幂等机制
240 0
|
负载均衡 网络性能优化
EMQ如何保证消息不重复消费?
EMQ(Erlang MQTT Broker)通过以下机制来保证消息不重复消费
763 2
|
消息中间件 NoSQL Redis
消息重复消费的问题
消息重复消费的问题
|
6月前
|
消息中间件 关系型数据库 MySQL
如何保证消息幂等
如何保证消息幂等
76 0
|
消息中间件 NoSQL Kafka
如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
为了提高应用程序的性能和可扩展性,很多应用程序开始采用消息队列(MQ)来处理消息。 MQ 可以将消息异步地发送到目的地,从而实现解耦、异步处理和流量控制等功能。 但是,MQ 也带来了一些问题,如消息重复消费和消息消费的幂等性问题。 本文将介绍 MQ 如何保证消息不被重复消费,并讨论如何保证消息消费的幂等性。
|
消息中间件 Kafka 测试技术
MQ 学习日志(七) 保证消息消费的顺序性
保证消息消费的顺序性
178 0
|
消息中间件 Kafka
Kafka消息的重复消费问题如何解决的 ?
Kafka 通过使用消费者组(Consumer Group)来解决消息的重复消费问题。
1614 0
|
消息中间件 监控 NoSQL
Rabbmit 重复消费的问题
最近遇到一个奇怪的问题,消费者在批量消费消息时,遇到该批次中出现部分重复消费导致业务异常。这些异常集中在某一时刻附近。
212 0