消息中间件(五)——如何保证消息的顺序性

       当我们的系统中引入了MQ之后,不得不考虑的一个问题是如何保证消息的顺序性,这是一个至关重要的事情,如果顺序错乱了,就会导致数据的不一致。

       比如:业务场景是这样的:我们需要根据mysql的binlog日志同步一个数据库的数据到另一个库中,加如在binlog中对同一条数据做了insert,update,delete操作,我们往MQ顺序写入了insert,update,delete操作的三条消息,那么根据分析,最终同步到另一个库中,这条数据是被删除了的。但是,如果这三条消息不是按照insert,update,delete顺序被消费,而是按照delete,insert,update的顺序被消费,那么最终这条数据是会保存到新库中的。这就导致了数据错乱了。下面分别讲解下RabbitMQ和Kafka是如何保证消息的顺序性。

1、RabbitMQ如何保证消息顺序性

1.1 RabbitMQ的消息不被顺序消费的情况

注意:queue(队列)中的消息只能被一个消费者所消费,然后消费者在消费消息的过程中是无序的。如上图所示,如果按照BAC的消费顺序,那么最终数据库中是被保存这条数据的。这和我们预期的结果不符,如果这样的情况很多,那么就造成了数据库中的数据完成不对,同步工作也是白费了。

1.2 RabbitMQ保证消息顺序性的措施

如图所示,RabbitMQ保证消息的顺序性,就是拆分多个 queue,每个 queue 对应一个 consumer(消费者),就是多一些 queue 而已,确实是麻烦点;或者就一个 queue 但是对应一个 consumer,然后这个 consumer 内部用内存队列做排队,然后分发给底层不同的 worker 来处理。

 

2、Kafka如何保证消息的顺序性

2.1 Kafka出现消息顺序性错乱的情况

       首先要说明一些Kafka的特性:比如一个topic,有三个partition,生产者在写的时候可以指定一个key,假设以订单id作为key,那么这个订单key相关的数据,一定会被分发到同一个partition中去,并且是有序的。同时消费者从 partition 中取出来数据的时候,也一定是有顺序的。

       还以上面的RabbitMQ一样的业务场景来说明Kafka出现消息没有顺序性的情况:假设订单id作为key的三条消息分别是执行:insert,update,delete操作。如果是按这个顺序执行的话,最终同步到其他库之后,这条数据是不存存在的。从Kafka的特性可以知道,这三条消息会分到一个partition中,一个消费者去消费这个partition中的数据,这个时候都能说是有序的。但是,单线程的情况下,吞吐量很低,一秒钟可能只能处理十多条消息,所以一般会采用多线程去提高吞吐量。线程之间的执行顺序和速度就不能保证有序了,如果thread1是拿到的delete,然后执行了,thread2拿到的消息是insert,然后执行,thread3拿到的消息是update,然后执行,所以最终这个订单的数据是会存到新库中的。这和原有的业务需求是不符合的。如图所示:

2.2 Kafka如何保证消息有序性

每个线程都只从一个内存队列中取数据,都相关的数据都存到同一个内存队列中,就保证了数据的有序性。

  • 3
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值