消息队列之kafka的重复消费

2022-04-11 18:39:39 浏览数 (1)

Kafka 是对分区进行读写的,对于每一个分区的消费,都有一个 offset 代表消息的写入分区时的位置,consumer 消费了数据之后,每隔一段时间,会把自己消费过的消息的 offset 提交一下。表示已记录当当前的消费位置,从这里开始消费。

这么个场景。数据 1/2/3 依次进入 kafka,kafka 会给这三条数据每条分配一个 offset,代表这条数据的序号,我们就假设分配的 offset 依次是 152/153/154。消费者从 kafka 去消费的时候,也是按照这个顺序去消费。假如当消费者消费了 offset=153 的这条数据,刚准备去提交 offset 到 zookeeper,此时消费者进程被重启了。那么此时消费过的数据 1/2 的 offset 并没有提交。于是1/2这两条消息又被重复消费了

如何保证幂等性

假设有个系统,消费一条消息就往数据库里插入一条数据,要是一个消息重复两次,数据就被重复消费了。当消费到第二次的时候,要判断一下是否已经消费过了,这样就保留了一条数据,从而保证了数据的正确性。

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

代码语言:javascript复制
幂等性,即一个请求,给你重复来多次,确保对应的数据是不会改变的,不能出错。

这里有以下几种方案

  • 先写数据库,根据主键查一下,如果这数据存在,就update
  • 先写redis,用set结构去重
  • 在进MQ之前,需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,当开始消费的时候,先根据这个 id 去比如 Redis 里查一下,如果没有消费过,这个 id 写 Redis。如果消费过了,那不处理了,保证别重复处理相同的消息即可。
  • 设置唯一索引去重

0 人点赞