一、什么是幂等性?
就是保证消费不被重复消费;
1.为什么消息会被重复消费呢?
在这里举个例子:
消费者准备提交消费的信息时,但还没有提交的时候,消费者进程被重启了(比如说宕机了,或者kill-9啦)。那么此时已经消费过的数据offset还没有提交。kafka也就不知道你消费了offset=153的那条数据。
消费者一旦重启,马上会找服务器说:哥们,把我上次消费到的那条数据之后的数据给我。数据1和数据2又发送过来了。等于对你来说,数据1和数据2在数据库里消费了2次。
2.如何保证消息不被重复消费呢?也就是保证消息重复消费的幂等性?
从业务举例
① 如果你拿个数据要写库,你先根据主键id查一下。如这数据都有了,你就别插入了。update一下。
② 如果你拿个数据是要更新表里的字段,直接update就好,幂等的。
③ 基于数据库的唯一性索引。因为有唯一性索引了。所以重复数据只会插入报错,不会导致数据库中出现重复的数据。
④ 如果你是写redis,那没问题了。每次都是set,天然幂等。
⑤如果不是上面的场景,那想的稍微复杂一点,需要生产者在发送消费的时候里面加一个全局性的唯一ID(UUID或者雪花算法),类似于订单ID之间的东西,先根据这个ID去redis中查一下,之前消费过嘛?如果没有消费过你就处理,然后把这个唯一性ID写Redis。如果消费过了,就不处理了。
二、消息是如何丢失的?
消息的可靠性传输怎么保证?
如何处理消息丢失的问题?
用MQ有个基本的原则,就是数据不能多一条,也不能少一条。不能多,就是刚刚说的重复消费和幂等性的问题, 不能少,就是说这条数据别搞丢了。
如果用MQ来传递非常核心的消息,比如说计费、扣费的一些消息,比如一个广告平台,计算系统是很重的一个业务,操作是很耗时的,所以说广告系统整体的架构里面,实际上是将计费做成异步的。然后中间就是加了一个MQ。广告主投放了一个广告,命名说好了,用户点击一次扣费1块钱。如果要是把用户点击一次,扣费的消费搞丢了,公司就会不断的少几块钱。
数据丢