消息的幂等性
消息的幂等性
重复的场景
按照数据进入Kafka的顺序,Kafka会给每条数据分配1个offset,代表这个数据的序号。消费者去消费的时候是按照这个顺序进行消费,假设消费者消费了offset=153
这个数据,刚准备提交offset到Zookeeper,此时消费者被重启了。那么消费过的数据,数据1和数据2并没有提交,Kafka不知道你已经消费了,那么重启之后,消费者会再次找Kafka从offset继续传递消息。由于之前的offset没有提交成功,导致Kafka把数据1和数据2再次传递,如果消费者没有去重的话,那么会导致重复消费。
举个例子。假设你有个系统,消费一条消息就往数据库里插入一条数据,要是你一个消息重复两次,你不就插入了两条,这数据不就错了?但是你要是消费到第二次的时候,自己判断一下是否已经消费过了,若是就直接扔了,这样不就保留了一条数据,从而保证了数据的正确性。 一条数据重复出现两次,数据库里就只有一条数据,这就保证了系统的幂等性。
幂等性,通俗点说,就一个数据,或者一个请求,给你重复来多次,你得确保对应的数据是不会改变的,不能出错。
方式
- 比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update 一下好。
- 比如你是写 Redis,那没问题了,反正每次都是 set,天然幂等性。
- 比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的 id,类似订单 id 之类的东西,然后你这里消费到了之后,先根据这个 id 去比如 Redis 里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个 id 写 Redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
- 比如基于数据库的唯一键来保证重复数据不会重复插入多条。因为有唯一键约束了,重复数据插入只会报错,不会导致数据库中出现脏数据。
如何保证 MQ 的消费是幂等性的,需要结合具体的业务来看。
Enjoy Reading This Article?
Here are some more articles you might like to read next: