当前位置:   article > 正文

如何保证MQ中消息的顺序性?_怎么保证mq顺序消费

怎么保证mq顺序消费

目录

1 问题分析

2 面试题回答

2.1 RabbitMQ

2.2 Kafka


想学习架构师构建流程请跳转:Java架构师系统架构设计

)

1 问题分析

其实这个也是用 MQ 的时候必问的话题,这是生产系统中常见的问题。

2 面试题回答

在消息队列(MQ)中保证消息的顺序性是一个关键的问题,特别是在处理涉及到数据一致性和完整性要求的高并发系统时。以下是一些常见的方法来保证消息的顺序性:

1. 使用单个消费者:让单个消费者处理队列中的所有消息,这样可以确保消息按照它们进入队列的顺序被处理。但是,这种方法在处理大量消息时可能会成为性能瓶颈。
2. 使用锁机制:使用锁机制可以防止多个消费者同时访问同一消息。例如,使用数据库锁或分布式锁来确保在任何时候只有一个消费者可以处理特定消息。然而,这种方法可能会增加系统的复杂性和开销。
3. 使用事务:将消息处理与事务结合使用可以确保消息的一致性和顺序性。在事务期间,消费者会锁定消息,进行一些处理,然后提交事务。如果事务失败,消息将被回滚到队列中,以便其他消费者可以重新处理。
4. 使用消息序列号:为每条消息分配一个唯一的序列号,消费者根据这个序列号来处理消息。当消费者处理完一条消息后,它可以将该序列号提交到下一个待处理的消息。这种方法可以避免消息丢失和重复处理的问题。
5. 使用可靠的消息队列:选择一个可靠的消息队列系统,如RabbitMQ或Apache Kafka,这些系统提供了消息持久化和确认机制,以确保消息不会丢失或被重复处理。
6. 限制并发处理:通过限制消费者的并发级别,可以控制同时处理多少消息。这样可以避免因同时处理大量消息而导致的问题,如死锁和竞态条件。
7. 考虑使用单向消息传递:采用单向消息传递模型,其中消息只能从生产者流向消费者,而不能返回生产者。这样可以减少因消息返回而引起的复杂性和性能问题。

综上所述,保证消息队列中消息的顺序性需要综合考虑系统的具体需求、性能要求和所使用的技术栈。选择合适的方法和工具对于实现可靠和高效的数据处理至关重要。

使用MySQL二进制日志(binlog)进行数据同步的系统的实现,其中涉及到一些关于数据顺序性的问题。

1. 首先,构建了一个系统,用于在两个MySQL数据库之间进行数据同步。这是一个高压力的系统,每天需要同步的数据量达到上亿条。
2. 其次,这个系统使用了MySQL的binlog,每当在源数据库中发生增删改操作时,就会生成相应的增删改3条binlog日志。这些日志会被发送到消息队列(MQ)中。
3. 然后,消费者会从MQ中消费这些日志,并按顺序依次执行。如果这个顺序出现错误,例如将“增加、修改、删除”的顺序错误地执行成了“删除、修改、增加”,那么数据的最终状态就会出错。
4. 最后,以一个例子说明了顺序的重要性。假设有一个数据应该按照“增加、修改、删除”的顺序进行操作。但由于某种原因,顺序被错误地执行成了“删除、修改、增加”,那么原本应该被删除的数据就会被保留下来,导致数据同步出错。

因此,这个例子强调了在处理这种数据同步系统时,确保消息顺序的重要性。

先看看顺序会错乱的俩场景:

  • RabbitMQ:一个 queue,多个 consumer。比如,生产者向 RabbitMQ 里发送了三条数据,顺序依次是 data1/data2/data3,压入的是 RabbitMQ 的一个内存队列。有三个消费者分别从 MQ 中消费这三条数据中的一条,结果消费者2先执行完操作,把 data2 存入数据库,然后是 data1/data3。这不明显乱了。

rabbitmq-order-01

  • Kafka:比如说我们建了一个 topic,有三个 partition。生产者在写的时候,其实可以指定一个 key,比如说我们指定了某个订单 id 作为 key,那么这个订单相关的数据,一定会被分发到同一个 partition 中去,而且这个 partition 中的数据一定是有顺序的
    消费者从 partition 中取出来数据的时候,也一定是有顺序的。到这里,顺序还是 ok 的,没有错乱。接着,我们在消费者里可能会搞多个线程来并发处理消息。因为如果消费者是单线程消费处理,而处理比较耗时的话,比如处理一条消息耗时几十 ms,那么 1 秒钟只能处理几十条消息,这吞吐量太低了。而多个线程并发跑的话,顺序可能就乱掉了。

kafka-order-01

解决方案

2.1 RabbitMQ

拆分多个 queue每个 queue 一个 consumer,就是多一些 queue 而已,然后这个 consumer 内部用内存队列做排队,然后汇总来处理,确实是麻烦点;或者就一个 queue 但是对应一个 consumer.

 rabbitmq-order-02

2.2 Kafka

  • 一个 topic,一个 partition,一个 consumer,内部单线程消费,单线程吞吐量太低,一般不会用这个。
  • 写 N 个内存 queue,具有相同 key 的数据都到同一个内存 queue;然后对于 N 个线程,每个线程分别消费一个内存 queue 即可,这样就能保证顺序性。

kafka-order-02

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/羊村懒王/article/detail/621039
推荐阅读
相关标签
  

闽ICP备14008679号