Code Monkey home page Code Monkey logo

mqidempotencytree's Introduction

MQIdempotencyTree

消息幂等性技术研究

消息中间件一般由三部分组成:
     1)Producer
     2) Consumer
     3) Broker(消息存储)

     为了保证消息的可达性,采取了超时重传机制,但是这可能导致消息总线或者业务方收到重复消息。

上半场流程:
     1)发送端MQ-Client 将消息发给服务端MQ-Server
     2) 服务端MQ-Server将消息落地
     3)服务端MQ-Server回ACK给发送端 MQ-Client

     如果 3)丢失,发送端MQ-Client超时后会重新发送,可能MQ-Server重复收到消息。

     为了避免消息重复发送,MQ系统内部必须要有一个内部消息ID,作为去重和幂等的依据,这个内部
     消息ID的特性是:
         1)全局唯一
         2)MQ生成,具备业务无关性。

     这样才能保证幂等
下半场流程:
     4)服务端MQ-Server将消息发送给接收端MQ-Client
     5) 接收端MQ-Client回ACK给服务端
     6)服务端MQ-Server将落地消息删除

     如果 5)丢失,服务端MQ-Server超时后重复发送消息,可能导致MQ-Client收到重复的消息。

     为保证业务幂等性,必须有一个biz-id,作为去重和幂等的依据,这个业务ID的特性是:
         1)对于同一个业务场景,全局唯一
         2)有业务消息发送发生成,业务相关,对MQ透明
         3)有业务消息消费方负责判重,以保证幂等。

     常见的如订单ID,支付ID等
MQ为了保证消息必达,消息上下半场均可能发送重复消息,如何保证消息的幂等性呢?

    上半场
         MQ-client生成inner-msg-id,保证上半场幂等。
         这个ID全局唯一,业务无关,由MQ保证。

    下半场
         业务发送方带入biz-id,
         业务接收方去重保证幂等。
         这个ID对单业务唯一,业务相关,对MQ透明。

     结论:幂等性,不仅对MQ有要求,对业务上下游也有要求
幂等的处理方式

      1)查询与删除是天然幂等的。
      2)唯一索引,防止新增脏数据。
      3)悲观锁for update
      5) 乐观锁 CAS 版本号,判断条件等。
      6)分布式锁
      7)状态机幂等,如果状态机已经处于下一个状态,这时候来了一个上一个状态的变更,理论是通不过的,这样的话,保证了有限状态机
         的幂等。
消息去重

      去重原则:
              1)幂等性  2)业务去重
      幂等性:
            无论这个业务请求被执行多少次,数据库的结构都是唯一的,不可改变的。
      去重策略:
            1:建立一个消息表,拿到这个消息做数据库的insert操作,给这个消息做一个唯一的主键
               或者唯一约束,那么就算出现重复消费的情况,就会导致主键冲突。
      高并发下去重:
            采用Redis去重,key天然支持原子性并要求不可重复,但是由于不再一个事务,要求有适当
            的补偿策略。

            2:利用Redis事务,主键(必须把全量的操作数据都存放在redis里,然后定时去和数据库)
               数据同步,即消费处理后,该处理本来应该保存在数据库的,先保存在Redis。
            3:利用Redis和关系型数据库一起做去重机制。
            5:拿到这个消息做Redis的set操作,Redis就是天然幂等性
            6:准备一个第三方介质来做消费处理,以Redis为例,给消息分配一个全局ID,只要消费国该消息,
               将以K-V形式写入Redis,那消费者开始消费前,先去Redis中查询有没有消费记录即可。

Kafka幂等性

      Kafka Producer 在实现时有以下两个重要机制:
            PID(Producer ID),用来标识每个 producer client;
            sequence numbers,client 发送的每条消息都会带相应的 sequence number,Server 端就是
            根据这个值来判断数据是否重复。

      PID:
          每个 Producer 在初始化时都会被分配一个唯一的 PID,这个 PID 对应用是透明的,完全没有暴露给
          用户。对于一个给定的 PID,sequence number 将会从0开始自增,每个 Topic-Partition 都会有一
          个独立的 sequence number。Producer 在发送数据时,将会给每条 msg 标识一个 sequence 
          number,Server 也就是通过这个来验证数据是否重复。这里的 PID 是全局唯一的,Producer 故障后
          重新启动后会被分配一个新的 PID,这也是幂等性无法做到跨会话的一个原因。

mqidempotencytree's People

Contributors

qiuqiuxiaomaomi avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.