第十章 RabbitMQ消息可靠性之MQ数据持久化

目录

一、引言

二、RabbitMQ传统持久化消息

三、惰性队列

[3.1. 惰性队列与传统持久化的主要区别:](#3.1. 惰性队列与传统持久化的主要区别:)

四、总结


一、引言

我们在使用MQ的过程中,除了生产者发送消息/连接MQ时存在的可靠性之外,MQ自身在收发消息时也存在着消息可靠性问题。如果对MQ的使用场景和机制不了解,就可能造成消息丢失等严重的问题。

在RabbitMQ中,消息的存储和处理方式可以根据不同的需求进行配置。主要有三种消息存储机制:非持久化消息、持久化消息和惰性队列。在非持久化的情况下,RabbitMQ会将接收到的信息保存在内存中以降低消息收发的延迟,提升吞吐性能。

但是将消息直接存储在内存这样会导致两个问题:

  1. 一旦MQ宕机,内存中的消息会丢失。

  2. 内存空间有限,当消费者故障或处理过慢时,会导致消息积压,引发MQ阻塞。

如上图所示,设置消息非持久化时,当大量消息请求来时,保存到内存的过程中,大量消息消费不及时会占满内存,这时MQ会将消息转移到磁盘(即Paged Out),此时大量消息处于阻塞状态。

因此,这就涉及到我们对消息进行持久化操作的问题。RabbitMQ实现数据持久化包括3个方面:

  • 交换机持久化
  • 队列持久化
  • 消息持久化

RabbitMQ为我们提供了两种持久化的方案,持久化消息和惰性队列。 下面我们就来分析讲解下两种方案的使用场景、使用方式及区别**。**

二、RabbitMQ传统持久化消息

在3.12版本前,rabbitmq一直使用传统方法作为持久化,就是将使用者创建的交换机、队列和消息时,将durable设置为true。以下是该属性在RabbitMQ的浏览器界面的队列是否持久化的配置选项

我们在使用Spring AMQP时,Spring已经为我们提供了默认的解决方案,在API中给我们将交换机、队列和消息配置持久化了,实现内存和磁盘双重存储。这保证了即使RabbitMQ服务器重启或崩溃,消息也不会丢失。这种机制虽然增加了一些处理延迟,但大大提高了消息的可靠性。

适用场景:需要确保消息不丢失的关键业务场景,如订单处理、交易信息等。

Spring源码中对消息队列默认设置为持久化,即durable = true

Spring源码中对交换机默认设置为持久化,即durable = true

Spring源码中对消息默认设置为持久化,即durable = true

队列设为持久化后的效果,我们通过黄线可以看到消息队列在每秒处理消息的速率和稳定性上都比较高,已经没有Paged Out消息积压的情况:

三、惰性队列

从RabbitMQ的3.6.0版本起,增加了Lazy Queue的概念即惰性队列,声明队列时需要指定x-queue-mode属性为lazy。 惰性队列特征如下:

  1. 接收到消息后直接存入磁盘,不再存储到内存

  2. 消费者要消费消息时才会从磁盘中读取并加载到内存(可以提前缓存部分消息到内存,最多2048条)

注:在3.12版本后,所有队列都是Lazy Queue模式,不需要指定属性,且无法更改。以下是3.6.0到3.12之间的RabbitMQ的版本设置惰性队列的方式:

通过RabbitMQ浏览器界面:

通过代码形式:

适用场景:Lazy queue 适用于消息量较大、消息消费速度较慢的场景。它可以处理大量的消息,而不会对内存造成过大的压力。传统的持久化方法适用于消息量较小、消息消费速度较快的场景,可以提供更低的延迟。

3.1. 惰性队列与传统持久化的主要区别:

数据存储位置:传统的持久化方法将消息和队列的数据存储在磁盘上,而 lazy queue 将消息存储在磁盘上,但队列的元数据仍存储在内存中。这意味着 lazy queue 在存储大量消息时可以减轻内存压力,而传统持久化方法需要将所有数据都存储在磁盘上。

内存使用:传统的持久化方法需要将所有消息和队列的元数据都加载到内存中,这可能会导致内存消耗过大。而 lazy queue 只需要加载当前需要处理的消息到内存中,减少了内存的使用量。

性能优化:Lazy queue 在设计上采用了一些性能优化策略。例如,它使用预取(prefetch)策略,只在需要时将一批消息加载到内存中,减少了磁盘读取的次数。此外,RabbitMQ 还采用了一些磁盘读写优化技术,如顺序写入和批量写入,以提高性能。

四、总结

相关推荐
一条泥憨鱼8 小时前
【Kafka】零基础学习教程
java·分布式·学习·kafka
贾伟康11 小时前
【共创稿事节】HarmonyOS 7.0 HiTraceChain分布式调用链:从接入到生产验证
分布式·harmonyos·可观测性·调用链·hitracechain
NiceZack1 天前
Hadoop 部署全流程教程:从新装 CentOS 到伪分布式与完全分布式
hadoop·分布式·centos
傻啦嘿哟1 天前
分布式爬虫架构:Redis+Scrapy打造企业级爬虫系统
分布式·爬虫·架构
starzy19901 天前
Kafka请求进门口:Processor是怎么把请求读上来的
分布式·kafka
骑着蜗牛撵大象3272 天前
558 万美元训出 671B 模型:DeepSeek-V3 算法与系统的协同拆解
分布式·算法·moe·deepseek-v3·mla·fp8训练
德迅云安全-上官2 天前
德迅游戏盾:面向 TCP 业务的分布式云安全防护方案
分布式·tcp/ip·游戏
未秃头的程序猿2 天前
@ConditionalOnMissingBean 把我配好的 RabbitMQ 手动 ack 吃掉了
后端·rabbitmq
麻瓜code2 天前
分布式锁演进:从一个用户下两单,到 Redisson,我改了四版
分布式·wpf
skywalk81632 天前
hive —— 多机 AI Agent 协同的任务总线:分布式,多节点同时运行,保障不会宕机
人工智能·hive·分布式