RabbitMQ持久化机制

之前其实已经写过一篇关于RabbitMQ持久化的文章,但那篇文章侧重代码层面的写入流程,对于持久化操作何时发生以及什么时候会刷新到磁盘等问题其实都没有搞清楚,这篇文章着重于关注这些问题。

消息什么时候需要持久化?

根据官方博文的介绍,RabbitMQ在两种情况下会将消息写入磁盘:

  1. 消息本身在publish的时候就要求消息写入磁盘;
  2. 内存紧张,需要将部分内存中的消息转移到磁盘;

消息什么时候会刷到磁盘?

  1. 写入文件前会有一个Buffer,大小为1M(1048576),数据在写入文件时,首先会写入到这个Buffer,如果Buffer已满,则会将Buffer写入到文件(未必刷到磁盘);
  2. 有个固定的刷盘时间:25ms,也就是不管Buffer满不满,每隔25ms,Buffer里的数据及未刷新到磁盘的文件内容必定会刷到磁盘;
  3. 每次消息写入后,如果没有后续写入请求,则会直接将已写入的消息刷到磁盘:使用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,消息的内容,消息对应的协议版本,消息内容格式(二进制还是其它)等等。

文件何时删除?

当所有文件中的垃圾消息(已经被删除的消息)比例大于阈值(GARBAGE_FRACTION = 0.5)时,会触发文件合并操作(至少有三个文件存在的情况下),以提高磁盘利用率。

publish消息时写入内容,ack消息时删除内容(更新该文件的有用数据大小),当一个文件的有用数据等于0时,删除该文件。

消息索引什么时候需要持久化?

索引的持久化与消息的持久化类似,也是在两种情况下需要写入到磁盘中:要么本身需要持久化,要么因为内存紧张,需要释放部分内存。

消息索引什么时候会刷到磁盘?

  1. 有个固定的刷盘时间:25ms,索引文件内容必定会刷到磁盘;
  2. 每次消息(及索引)写入后,如果没有后续写入请求,则会直接将已写入的索引刷到磁盘,实现上与消息的timeout刷盘一致。

消息索引在磁盘文件中的格式

每个队列会对队列中的消息维护一个索引,每入队列一个消息,索引加1,索引在持久化时,以2^14个(16384)entry为单位组成一个文件(Segment)。索引在写入时,未必会按序写入,为了避免过多的磁盘寻址,索引信息会首先保存在Journal文件中,当该文件中的entry数量达到65536个时,会将其中的内容写入到Segment文件中。其中Journal保存于$MNESIA/queues/md5(queueName)/journal.jif文件中,索引保存于$MNESIA/queues/md5(queueName)/x.idx文件中,其中的x为数字编号,类似于消息文件的编号。

索引信息在Segment文件中的格式有两种:

  1. 对应publish消息:<<1:1, IsPersistent:1, RelSeq:14, MsgId:16/binary, Expiry:8/binary>>;
  2. 对应deliver或者ack消息:<<01:2, RelSeq:14>>。

文件何时删除?

rabbit_msg_index模块为每一个Segment维护一个unacked计数,每publish一个消息加1,每ack一个消息减1,当unacked=0时,文件删除。

注:持久化文件的大小可通过配置参数msgstore_file_size_limit修改,journal文件中最大entry数量可通过参数queue_index_max journal_entries配置,具体参见这里

最后与小伙伴们分享

看到某度百做在做推广,一分钱领取手套,冬天啦,大家速度,链接点此~~~

图片如下:

时间: 2024-08-12 22:59:11

RabbitMQ持久化机制的相关文章

【转】RabbitMQ基础——和——持久化机制

这里原来有一句话,触犯啦天条,被阉割!!!! 首先不去讨论我的日志组件怎么样.因为有些日志需要走网络,有的又不需要走网路,也是有性能与业务场景的多般变化在其中,就把他抛开,我们只谈消息RabbitMQ. 那么什么是RabbitMQ,它是用来解决什么问题的,性能如何,又怎么用?我会在下面一一阐述,如有错误,不到之处,还望大家不吝赐教. RabbitMQ简介 必须一提的是rabbitmq是由LShift提供的一个消息队列协议(AMQP)的开源实现,由以高性能.健壮以及可伸缩性出名的Erlang写成(

Redis数据持久化机制AOF原理分析二

Redis数据持久化机制AOF原理分析二 分类: Redis 2014-01-12 15:36  737人阅读  评论(0)  收藏  举报 redis AOF rewrite 目录(?)[+] 本文所引用的源码全部来自Redis2.8.2版本. Redis AOF数据持久化机制的实现相关代码是redis.c, redis.h, aof.c, bio.c, rio.c, config.c 在阅读本文之前请先阅读Redis数据持久化机制AOF原理分析之配置详解文章,了解AOF相关参数的解析,文章链

Redis源码剖析和注释(十八)--- Redis AOF持久化机制

Redis AOF持久化机制 1. AOF持久化介绍 Redis中支持RDB和AOF这两种持久化机制,目的都是避免因进程退出,造成的数据丢失问题. RDB持久化:把当前进程数据生成时间点快照(point-in-time snapshot)保存到硬盘的过程,避免数据意外丢失. AOF持久化:以独立日志的方式记录每次写命令,重启时在重新执行AOF文件中的命令达到恢复数据的目的. Redis RDB持久化机制源码剖析和注释 AOF的使用:在redis.conf配置文件中,将appendonly设置为y

Redis提供的持久化机制(RDB和AOF)

Redis提供的持久化机制 Redis是一种高性能的数据库,可以选择持久化,也可以选择不持久化. 如果要保存,就会存在数据同步的问题,可以简单认为一份数据放在内存中(快照),一份数据放在磁盘上,Redis提供了很灵活的持久化办法: Redis提供了RDB持久化和AOF持久化,本篇文章中将会对这两种机制进行一些对比 RDB机制的优势和略施 RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘. 也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为

ActiveMQ消息持久化机制

为了避免意外宕机以后丢失信息,需要做到重启后可以恢复消息队列,消息系统一般都会采用持久化机制. ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,无论使用哪种持久化方式,消息的存储逻辑都是一致的. 就是在发送者将消息发送出去后,消息中心首先将消息存储到本地数据文件.内存数据库或者远程数据库等,然后试图将消息发送给接收者,发送成功则将消息从存储中删除,失败则继续尝试. 消息中心启动以后首先要检查制定的存储位置,如果有未发送成功的消息,则需要把消息发送出去. >>

细说Redis持久化机制

概述 Redis不仅能够作为缓存来使用,也能够作为内存数据库. Redis作为内存数据库使用时.必需要解决一个问题:数据的持久性.有些将Redis作为缓存使用的场景也需要将缓存的数据持久化到存储介质上,这样在Redis重新启动后仍然能对热点数据提供缓存服务.不会由于缓存数据的缺失而对整个系统造成冲击. 本文就Redis内置的持久化机制进行说明. Redis持久化方式 Redis内置的持久化方式有两种:快照方式和AOF方式. 快照方式是将某一时点的内存数据写到硬盘上.AOF方式是将写入的命令记录在

Redis 学习之持久化机制、发布订阅、虚拟内存

该问使用centos6.5 64位  redis3.2.8 一.持久化机制 Redis是一个支持持久化的内存数据库,redis会经常将内存中的数据同步到硬盘上来保证数据持久化,从而避免服务器宕机数据丢失问题,或者减少服务器内存消耗提高性能. 持久化方式: 1.Snapshotting:快照,redis默认持久化方式,这种方式是将内存中的数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb.可以通过配置设置自动做快照持久化的方式.我们可以配置redis在n秒内如果超过m个key被修改

Redis持久化机制

[RDB与AOF两种持久化模式的对比,实现原理] [RDB模式] fork一个进程,遍历hash table,利用copy on write,把整个db dump保存下来. save, shutdown, slave 命令会触发这个操作. 粒度比较大,如果save, shutdown, slave 之前crash了,则中间的操作没办法恢复. [AOF模式] 把写操作指令,持续的写到一个类似日志文件里.(类似于从postgresql等数据库导出sql一样,只记录写操作) 粒度较小,crash之后,

redis的持久化机制

redis简介 redis是一个基于内存的nosql数据库,和传统关系数据最大的区别就是数据是存在内存中而不是硬盘上,从而带来了tps的巨大提升.但是基于内存的数据库最大的缺陷就是机器断电或者系统崩溃后数据会全部丢失.但是redis可以有一套自己的持久化机制,可以让他在系统断电或者崩溃后尽可能的少丢数据.下面就来总结下redis提供的持久化机制的各个特性. redis提供的持久化选项 redis一共提供两种不同的持久化方法.一种是快照(snapshotting) 它可以将存于某一时刻的数据都写入