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

ops/2024/10/20 1:20:27/

目录

一、引言

二、RabbitMQ传统持久化消息

三、惰性队列

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 还采用了一些磁盘读写优化技术,如顺序写入和批量写入,以提高性能。

四、总结


http://www.ppmy.cn/ops/124927.html

相关文章

vue3学习记录-watch

vue3学习记录-watch 1.watch2.watchEffect2.1 watchEffect使用2.2 watchEffect好处2.2.1 消除手动维护依赖列表的负担2.2.2 侦听一个嵌套数据结构中的几个属性 1.watch 直接总结下。。。 <script setup> import { ref, reactive, computed, watch } from vueconst inpu…

ubuntu20.04 上 opencv4 源码编译安装

下载&#xff1a; 1、opencv 4.9 2、opencv_contrilb 4.x 基础依赖库 sudo apt install -y cmake make sudo apt install -y build-essential sudo apt install -y libgtk2.0-dev sudo apt install -y libavcodec-dev sudo apt install -y libavformat-dev sudo apt install …

Appium Device Farm安装教程

环境要求&#xff1a;Appium version ≥ 2.4.X 安装appium npm install -g appium2.11.3 如果安装提示如下问题 npm error code EEXIST npm error syscall rename npm error path /Users/wan/.npm/_cacache/tmp/d5787519 npm error dest /Users/wan/.npm/_cacache/content-…

小米电机与STM32——CAN通信

背景介绍&#xff1a;为了利用小米电机&#xff0c;搭建机械臂的关节&#xff0c;需要学习小米电机的使用方法。计划采用STM32驱动小米电机&#xff0c;实现指定运动&#xff0c;为此需要了解他们之间的通信方式&#xff0c;指令写入方法等。花了很多时间学习&#xff0c;但网络…

LVS-DR+Keepalived 高可用群集部署

LVS-DRKeepalived 高可用群集部署 Keepalived 的工作原理LVSKeepalived 高可用群集部署配置负载调度器&#xff08;主、备相同&#xff09;关闭防火墙和核心防护及准备IPVS模块配置keeplived&#xff08;主、备DR 服务器上都要设置&#xff09;启动 ipvsadm 服务调整 proc 响应…

2024 - 两台CentOS服务器上的1000个Docker容器(每台500个)之间实现UDP通信(C语言版本)

两台CentOS服务器上的1000个Docker容器&#xff08;每台500个&#xff09;之间实现UDP通信(C语言版本) 给女朋友对象写得&#xff0c;她不会&#xff0c;我就写了一个 为了帮助您在两台CentOS服务器上的1000个Docker容器&#xff08;每台500个&#xff09;之间实现UDP通信&…

Web安全常用工具 (持续更新)

前言 本文虽然是讲web相关工具&#xff0c;但在在安全领域&#xff0c;没有人是先精通工具&#xff0c;再上手做事的。鉴于web领域繁杂戎多的知识点&#xff08;工具是学不完的&#xff0c;哭&#xff09;&#xff0c;如果你在本文的学习过程中遇到没有学过的知识点&#xff0…

zookeeper kafka集群配置

一.下载安装包 地址&#xff1a;https://download.csdn.net/download/cyw8998/16579797 二.配置文件 zookeeper.properties dataDir/data/kafka/zookeeper_data/zookeeper # the port at which the clients will connect clientPort2181 # disable the per-ip limit on the…