1.消息持久化原理
所有队列中的消息都以append的方式写到一个文件中,当这个文件的大小超过指定的限制大小后,关闭这个文件再创建一个新的文件供消息的写入。文件名(*.rdq)从0开始然后依次累加。当某个消息被删除时,并不立即从文件中删除相关信息,而是做一些记录,当垃圾数据达到一定比例时,启动垃圾回收处理,将逻辑相邻的文件中的数据合并到一个文件中。
rabbitmq在启动时会创建msg_store_persistent,msg_store_transient两个进程,一个用于持久消息的存储,一个用于内存不够时,将存储在内存中的非持久化数据转存到磁盘中。所有队列的消息的写入和删除最终都由这两个进程负责处理,而消息的读取则可能是队列本身直接打开文件进行读取,也可能是发送请求由msg_store_persisteng/msg_store_transient进程进行处理。
在进行消息的存储时,rabbitmq会在ets表中记录消息在文件中的映射,以及文件的相关信息。消息读取时,根据消息ID找到该消息所存储的文件,在文件中的偏移量,然后打开文件进行读取。消息的删除只是从ets表删除指定消息的相关信息,同时更新消息对应存储的文件的相关信息(更新文件有效数据大小)。
由于执行消息删除操作时,并不立即对在文件中对消息进行删除,也就是说消息依然在文件中,仅仅是垃圾数据而已。当垃圾数据超过一定比例后(默认比例为50%),并且至少有三个及以上的文件时,rabbitmq触发垃圾回收。垃圾回收会先找到符合要求的两个文件(根据#file_summary{}中left,right找逻辑上相邻的两个文件,并且两个文件的有效数据可在一个文件中存储),然后锁定这两个文件,并先对左边文件的有效数据进行整理,再将右边文件的有效数据写入到左边文件,同时更新消息的相关信息(存储的文件,文件中的偏移量),文件的相关信息(文件的有效数据,左边文件,右边文件),最后将右边的文件删除。
2.消息什么时候需要持久化?
RabbitMQ在两种情况下会将消息写入磁盘:
消息本身在publish的时候就要求消息写入磁盘;
内存紧张,需要将部分内存中的消息转移到磁盘;
消息什么时候会刷到磁盘?
写入文件前会有一个Buffer,大小为1M(1048576),数据在写入文件时,首先会写入到这个Buffer,如果Buffer已满,则会将Buffer写入到文件(未必刷到磁盘);
有个固定的刷盘时间:25ms,也就是不管Buffer满不满,每隔25ms,Buffer里的数据及未刷新到磁盘的文件内容必定会刷到磁盘;
每次消息写入后,如果没有后续写入请求,则会直接将已写入的消息刷到磁盘:使用Erlang的receive x after 0来实现,只要进程的信箱里没有消息,则产生一个timeout消息,而timeout会触发刷盘操作。
消息在磁盘文件中的格式
消息保存于$MNESIA/msg_store_persistent/x.rdq文件中,其中x为数字编号,从1开始,每个文件最大为16M(16777216),超过这个大小会生成新的文件,文件编号加1。消息以以下格式存在于文件中:
<<Size:64, MsgId:16/binary, MsgBody>>
MsgId为RabbitMQ通过rabbit_guid:gen()每一个消息生成的GUID,MsgBody会包含消息对应的exchange,routing_keys,消息的内容,消息对应的协议版本,消息内容格式(二进制还是其它)等等。
4.文件何时删除?
当所有文件中的垃圾消息(已经被删除的消息)比例大于阈值(GARBAGE_FRACTION = 0.5)时,会触发文件合并操作(至少有三个文件存在的情况下),以提高磁盘利用率。
publish消息时写入内容,ack消息时删除内容(更新该文件的有用数据大小),当一个文件的有用数据等于0时,删除该文件。
参考列表:
http://blog.csdn.net/yongche_shi/article/details/51500534
http://blog.csdn.net/yongche_shi/article/details/51500623
分享到:
相关推荐
本教程将详细介绍如何在Spring Boot应用中结合RabbitMQ实现消息确认、消息持久化、备用交换机以及死信交换机等功能。 首先,让我们理解这些概念: 1. **消息确认**:在RabbitMQ中,消息确认(Message ...
RabbitMQ Mirror机制是RabbitMQ中的一种高可用性机制,旨在提供消息队列的高可用性和持久化。Mirror机制的核心是镜像队列(Mirror Queue),它是一个特殊的Backing Queue,内部包裹了一个普通的Backing Queue,用于...
RabbitMQ 的消息持久化是指在 RabbitMQ Server 中保留消息的机制,以便在 Server 崩溃或重启后可以恢复消息。消息持久化是通过在交换器、队列和消息三个方面实现的。 第一步,交换器的持久化。交换器是 RabbitMQ 中...
Confirm 机制的性能对应用的影响很大,测试显示,在单台服务器上开 8 个 queue,消息持久化,1kb 大小的消息,不开 confirm 时 QPS 28k,开启 confirm 后 QPS 降到 21k。 Confirm 机制的主干流程可以分为以下几个...
- **优化持久化策略**:根据业务需求,可以选择是否对所有消息进行持久化。非关键消息可以使用非持久化模式,以提高速度。 总之,RabbitMQ的Confirm机制是保障消息不丢失的重要工具,但它确实会对性能产生影响。...
* 消息持久化:RabbitMQ 提供了消息持久化机制,确保消息的安全。 demo 下面是一些使用 RabbitMQ 的 demo 例子: demo(1):简单的消息队列 * 生产者发送消息到 RabbitMQ 服务器。 * 消费者从 RabbitMQ 服务器...
RabbitMQ之所以受欢迎,主要因为它具有异步、削峰、负载均衡等高级功能,并且还提供了消息持久化机制,确保了即使在系统故障的情况下,消息也不会丢失。此外,RabbitMQ还实现了生产者和消费者之间的解耦,提高了系统...
RabbitMQ支持消息确认机制,允许服务器确认消息是否已被消费者成功处理,从而保证消息的可靠性。 8. **持久化** 通过配置,可以将消息和队列设置为持久化,即使服务器重启,数据也不会丢失。 9. **集群和高可用...
- 消息持久化是确保即使RabbitMQ服务重启,消息也不会丢失的关键特性。这包括交换机(exchange)、队列(queue)和消息(message)的持久化。 - 在声明交换机时,通过设置`durable => true`可使其变为持久化的。 - 声明...
本文将深入探讨RabbitMQ工作队列的实现,包括消息确认机制、消息持久化以及公平调度等关键知识点。 首先,让我们理解工作队列的概念。工作队列是一种负载均衡策略,它将任务分发到多个工作者进程,以处理大量并发...
RabbitMQ 是一种基于 AMQP 高级消息队列协议的消息队列技术,具有消费并不需要确保提供方存在、实现服务之间的高度解耦、持久化机制、进程消息、队列中的信息保存、消费者和生产者之间的解耦等特点。 使用 RabbitMQ...
7. **持久化**:如果需要保证消息即使在服务器重启后也能保留,可以启用消息和队列的持久化。这使得RabbitMQ能够在重启后恢复消息,并确保不丢失未处理的数据。 8. **负载均衡与高可用性**:通过设置集群和镜像队列...
持久化消息主要是指我们机器在不可抗力因素等情况下挂掉了,消息不会丢失的机制。 3.综合技术实现 可靠性、灵活的路由、集群、事务、高可用的队列、消息排序、问题追踪、可视化管理工具、插件系统等等。 RabbitMq ...
性能测试主要关注RabbitMQ的消息发送和接收能力,特别关注了消息的应答机制和持久化功能,以保证消息的可靠传输。测试涵盖了各种生产者与消费者数量的组合场景,以模拟实际应用中的复杂情况。 2.2.1 **单机模式测试...
- **rabbitmq_queue_declare**: 声明一个队列,可以指定是否持久化、排他或自动删除。 - **rabbitmq_basic_publish**: 发布消息到指定的交换机,交换机会根据绑定规则将消息路由到相应的队列。 - **rabbitmq_...
持久化机制对于保证消息传递的可靠性至关重要。 ##### 3.3 综合技术实现 从技术实现角度来看,RabbitMQ具有以下优势: - **可靠性**:通过多种机制确保消息的可靠传输。 - **灵活的路由**:支持多种路由策略,...
3. **创建消息队列**:在RabbitMQ管理界面或通过代码创建一个消息队列,定义队列的名称、持久化等属性。 4. **配置TP6**:在 TP6 的配置文件 `config.php` 或特定的环境配置文件中添加RabbitMQ的连接信息,如主机名...
- **插件机制**:RabbitMQ提供丰富的插件,如监控、审计、持久化策略等。 - **集成Spring框架**:通过Spring AMQP库,简化Java应用中的RabbitMQ集成。 7. **消息确认机制**: 生产者和消费者可以启用消息确认,...