当前位置:首页 > 数码 > RabbitMQ中的消息持久化策略与存储优化实践 (rabbit中文翻译)

RabbitMQ中的消息持久化策略与存储优化实践 (rabbit中文翻译)

admin7个月前 (05-01)数码35

在 RabbitMQ 消息队列中,消息的可靠性传输和持久化至关重要。本文将介绍 RabbitMQ 中的消息持久化策略,并提供一些存储优化实践,帮助您确保消息的可靠性和系统的性能。

一、消息持久化策略

  1. 持久化交换器(Durable Exchanges):通过在创建交换器时将其标记为持久化,使其在 RabbitMQ 节点重启后仍然存在。持久化的交换器可以确保消息在发送到队列之前不会丢失。
  2. 持久化队列(Durable Queues):通过在创建队列时将其标记为持久化,使其在节点重启后仍然存在。持久化的队列可以确保消息在节点重启后不会丢失。
  3. 持久化消息(Persistent Messages):消息的默认持久化策略是非持久化的,这意味着如果 RabbitMQ 节点重启,消息可能会丢失。为了确保消息的可靠性,可以将消息标记为持久化,使其在节点重启后仍然存在。
  4. 持久化发布确认(Publisher Confirms):通过启用发布确认机制,生产者可以在消息成功投递到交换器后,收到来自 RabbitMQ 的确认。这种方式可以确保消息在发送过程中不会丢失。

二、存储优化实践

  1. 存储引擎选择:RabbitMQ 使用 Erlang Mnesia 数据库作为默认的存储引擎,但对于大规模的消息队列,推荐使用更高效的存储引擎,如 RocksDB 或 PostgreSQL。这些存储引擎可以提供更好的性能和可扩展性。
  2. 持久化模式选择:RabbitMQ 支持两种消息持久化模式:同步持久化和异步持久化。同步持久化会在消息写入磁盘后才返回确认,而异步持久化则不会等待磁盘写入完成。如果对消息的可靠性要求较高,可以选择同步持久化,但需要注意会影响性能。
  3. 消息压缩:对于大型消息队列,可以考虑启用消息压缩功能,将消息在存储和传输过程中进行压缩。这样可以减少存储空间和网络带宽的消耗。
  4. 消息过期策略:对于一些业务场景,消息可能会在一段时间后变得无效。为了避免占用过多的存储空间,可以设置消息的过期时间,在一定时间后自动删除过期消息。
  5. 定期清理和维护:定期清理不再需要的队列、交换器和消息,可以释放存储空间并提升系统性能。同时,还可以注意监控存储的使用情况,确保充分利用存储资源。
  6. 数据分区和分片:对于大规模的消息队列,可以考虑将数据进行分区和分片存储,以便实现更好的负载均衡和扩展性。这样可以将消息存储在多个物理节点上,提高系统的并发处理能力。

三、关键注意事项

  1. 系统容量规划:在设计和部署消息队列系统时,需要考虑到预计的消息量和存储需求,并合理规划系统的容量,以确保系统能够满足业务需求。
  2. 定期监控和调优:定期监控队列的存储使用情况、性能指标和运行状态,及时发现问题并进行调优,以保证系统的可靠性和性能。
  3. 安全性保护:为了保护消息的安全性,可以考虑启用 SSL/TLS 加密和身份验证机制,以防止未经授权的访问和数据泄露。
  4. 数据备份和恢复:定期进行消息队列数据的备份,并建立灾难恢复机制,以避免数据丢失和系统故障。

结论

在 RabbitMQ 消息队列中,消息的可靠性传输和持久化是至关重要的。通过使用消息持久化策略,如持久化交换器、持久化队列和持久化消息,可以确保消息在节点重启后不会丢失。同时,通过存储优化实践,如选择合适的存储引擎、压缩消息、设置消息过期策略等,可以提升系统的性能和存储效率。在实际应用中,建议根据业务需求和系统规模,制定一套完整的存储优化方案,并进行持续监控和调优,以确保消息的可靠性和系统的性能。

rabbitmq保证消息不丢失?

数据不能多,也不能少,不能多是说消息不能重复消费,这个我们上一节已解决;不能少,就是说不能丢失数据。如果mq传递的是非常核心的消息,支撑核心的业务,那么这种场景是一定不能丢失数据的。

2.丢失数据场景

丢数据一般分为两种,一种是mq把消息丢了,一种就是消费时将消息丢了。下面从rabbitmq和kafka分别说一下,丢失数据的场景,(1)rabbitmqA:生产者弄丢了数据生产者将数据发送到rabbitmq的时候,可能在传输过程中因为网络等问题而将数据弄丢了。B:rabbitmq自己丢了数据如果没有开启rabbitmq的持久化,那么rabbitmq一旦重启,那么数据就丢了。所依必须开启持久化将消息持久化到磁盘,这样就算rabbitmq挂了,恢复之后会自动读取之前存储的数据,一般数据不会丢失。除非极其罕见的情况,rabbitmq还没来得及持久化自己就挂了,这样可能导致一部分数据丢失。C:消费端弄丢了数据主要是因为消费者消费时,刚消费到,还没有处理,结果消费者就挂了,这样你重启之后,rabbitmq就认为你已经消费过了,然后就丢了数据。

3.如何防止消息丢失

(1)rabbitmqA:生产者丢失消息①:可以选择使用rabbitmq提供是事物功能,就是生产者在发送数据之前开启事物,然后发送消息,如果消息没有成功被rabbitmq接收到,那么生产者会受到异常报错,这时就可以回滚事物,然后尝试重新发送;如果收到了消息,那么就可以提交事物

();//开启事物try{//发送消息}catch(Exection e){();//回滚事物//重新提交}复制代码

缺点:rabbitmq事物已开启,就会变为同步阻塞操作,生产者会阻塞等待是否发送成功,太耗性能会造成吞吐量的下降。

rabbit中文翻译

②:可以开启confirm模式。在生产者哪里设置开启了confirm模式之后,每次写的消息都会分配一个唯一的id,然后如何写入了rabbitmq之中,rabbitmq会给你回传一个ack消息,告诉你这个消息发送OK了;如果rabbitmq没能处理这个消息,会回调你一个nack接口,告诉你这个消息失败了,你可以进行重试。而且你可以结合这个机制知道自己在内存里维护每个消息的id,如果超过一定时间还没接收到这个消息的回调,那么你可以进行重发。

//开启();//发送成功回调public void ack(String messageId){}// 发送失败回调public void nack(String messageId){//重发该消息}复制代码

二者不同事务机制是同步的,你提交了一个事物之后会阻塞住,但是confirm机制是异步的,发送消息之后可以接着发送下一个消息,然后rabbitmq会回调告知成功与否。 一般在生产者这块避免丢失,都是用confirm机制。B:rabbitmq自己弄丢了数据设置消息持久化到磁盘。设置持久化有两个步骤:①创建queue的时候将其设置为持久化的,这样就可以保证rabbitmq持久化queue的元数据,但是不会持久化queue里面的数据。②发送消息的时候讲消息的deliveryMode设置为2,这样消息就会被设为持久化方式,此时rabbitmq就会将消息持久化到磁盘上。 必须要同时开启这两个才可以。

而且持久化可以跟生产的confirm机制配合起来,只有消息持久化到了磁盘之后,才会通知生产者ack,这样就算是在持久化之前rabbitmq挂了,数据丢了,生产者收不到ack回调也会进行消息重发。C:消费者弄丢了数据使用rabbitmq提供的ack机制,首先关闭rabbitmq的自动ack,然后每次在确保处理完这个消息之后,在代码里手动调用ack。这样就可以避免消息还没有处理完就ack。

RabbitMQ 进阶- 阿里云服务器部署RabbitMQ集群

如果RabbitMQ集群只有一个broker节点,那么该节点的失效将导致整个服务临时性的不可用,并且可能会导致message的丢失(尤其是在非持久化message存储于非持久化queue中的时候)。可以将所有message都设置为持久化,并且使用持久化的queue,但是这样仍然无法避免由于缓存导致的问题:因为message在发送之后和被写入磁盘并执行fsync之间存在一个虽然短暂但是会产生问题的时间窗。通过publisher的confirm机制能够确保客户端知道哪些message已经存入磁盘,尽管如此,一般不希望遇到因单点故障导致服务不可用。

如果RabbitMQ集群是由多个broker节点构成的,那么从服务的整体可用性上来讲,该集群对于单点失效是有弹性的,但是同时也需要注意:尽管exchange和binding能够在单点失效问题上幸免于难,但是queue和其上持有的message却不行,这是因为queue及其内容仅仅存储于单个节点之上,所以一个节点的失效表现为其对应的queue不可用。

为了提高程序的吞吐量,保持消息的可靠性,一台机器挂了后,RabbitMQ能够正常生产,消费消息。

rabbitmq有三种模式:单机模式,普通集群模式,镜像集群模式

Demo级别的,一般只是本机测试玩玩而已,生产环境下不会用的。

在多台机器上启动多个rabbitmq实例,每个机器启动一个。 但是你创建的queue,只会放在一个rabbtimq实例上,但是每个实例都同步queue的元数据(存放含queue数据的真正实例位置)。消费的时候,实际上如果连接到了另外一个实例,那么那个实例会从queue所在实例上拉取数据过来。

示意图

这种方式确实很麻烦,也不怎么好,没做到所谓的分布式,就是个普通集群。 普通集群的方式,确实达到了消息的高可用,但没办法保证可靠性,没做到分布式,简而言之,只是一个普通的集群。

这种模式,才是所谓的rabbitmq的高可用模式,跟普通集群模式不一样的是,你创建的queue,无论元数据还是queue里的消息都会存在于多个实例上,然后每次你写消息到queue的时候,都会自动把消息到多个实例的queue里进行消息同步。

上图中每个节点有一个queue,生产者生产完毕数据后投递到指定交换机的队列,交换机的队列进行消息同步。

每个节点queue都有一个完整的rabbitmq节点,所以这种方式叫做镜像集群

好处: 任何一个节点宕机后,其它节点不受影响,正常使用

坏处:

确保机器中安装了Docker,若未安装,可看:【云原生】Docker入门 – 阿里云服务器Linux环境下安装Docker

查看拉取的镜像

成功运行

设置节点1

浏览器输入 您的ip地址

再次测试即可成功~

File —> New —> Project —> Maven —> 直接Next 进入下一步创建普通的Maven工程即可

创建一个默认的Maven聚合工程,将src文件夹删除,该工程就是一个Maven聚合工程

引入依赖如下:

在项目内,新建一个Moudle,rabbitmq-order-producer 默认Maven工程,下一步即可

在项目内,新建一个Moudle,rabbitmq-order-cousumer 默认Maven工程,下一步即可

Maven聚合工程创建完成图

Maven依赖图

自行手写MainApplication即可

创建完成!

编写完成!

启动消费者

交换机

成功消费数据!

已成功同步消息~

免责声明:本文转载或采集自网络,版权归原作者所有。本网站刊发此文旨在传递更多信息,并不代表本网赞同其观点和对其真实性负责。如涉及版权、内容等问题,请联系本网,我们将在第一时间删除。同时,本网站不对所刊发内容的准确性、真实性、完整性、及时性、原创性等进行保证,请读者仅作参考,并请自行核实相关内容。对于因使用或依赖本文内容所产生的任何直接或间接损失,本网站不承担任何责任。

标签: RabbitMQ

“RabbitMQ中的消息持久化策略与存储优化实践 (rabbit中文翻译)” 的相关文章

轻松了解顺序消费-RabbitMQ-死信队列和延时队列-深化浅出 (轻松了解顺序怎么写)

轻松了解顺序消费-RabbitMQ-死信队列和延时队列-深化浅出 (轻松了解顺序怎么写)

1.引言 在当天的文章中,咱们来聊一聊RabbitMQ,这是小❤在上班中用的最早的信息两边件,关键用于少量数据的异步消费。 2.RabbitMQ 2.1外围组件 Rabbi...

RabbitMQ信息发送和接纳形式概览 (rabbit中文翻译)

RabbitMQ信息发送和接纳形式概览 (rabbit中文翻译)

channel.basicQos(0,1,false):0示意对信息的大小有限度,1示意每次只准许生产一条,false示意该限度不作用于channel。同时,咱们驳回手工ACK的形式,由于咱们性能文件...

RabbitMQ消息顺序性解密-确保消息的正确顺序 (rabbit中文翻译)

RabbitMQ消息顺序性解密-确保消息的正确顺序 (rabbit中文翻译)

引言 RabbitMQ 是一个流行的消息队列系统,但它本身并不提供严格的消息顺序保证。这对于一些需要严格按照顺序处理消息的应用场景来说是一个挑战。本文将探讨如何在使用 RabbitMQ 时实现消...

RabbitMQ与消息限流策略的完美结合-保障消息可靠性和系统稳定性 (rabbitmq)

RabbitMQ与消息限流策略的完美结合-保障消息可靠性和系统稳定性 (rabbitmq)

引言 在互联网时代,高并发访问已成为许多应用系统面临的常见挑战。对于需要处理大量请求的系统来说,如何保证系统的稳定性和可靠性是一个关键问题。RabbitMQ作为一种可靠的消息队列中间件,可以帮助...

WebSockets-与-的结合-RabbitMQ-实时协作的秘诀 (websocket和http区别)

WebSockets-与-的结合-RabbitMQ-实时协作的秘诀 (websocket和http区别)

引言 实时协作是现代软件开发中非常重要的一个方面。为了实现实时协作,一种常见的做法是将消息队列与WebSocket技术相结合。 RabbitMQ 简介 RabbitMQ是一个功能强大的消息...

Centos7下装置部署RabbitMQ-一文看尽 (centos7)

Centos7下装置部署RabbitMQ-一文看尽 (centos7)

前言 RabbitMQ是一个开源的弱小的企业信息系统,支持干流的操作系统,支持多种开发言语。咱们名目中经常使用RabbitMQ作为信息队列,解耦业务,构建高牢靠的信息队列系统。RabbitM...