RocketMQ消息存储

RocketMQ消息存储

1 CommitLog

要想知道RocketMQ如何存储消息,我们先看看CommitLog。在RocketMQ中,所有topic的消息都存储在一个称为CommitLog的文件中,该文件默认最大为1GB,超过1GB后会轮到下一个CommitLog文件。通过CommitLog,RocketMQ将所有消息存储在一起,以顺序IO的方式写入磁盘,充分利用了磁盘顺序写减少了IO争用提高数据存储的性能,

消息在CommitLog中的存储格式如下:

image.png

· 4字节表示消息的长度,消息的长度是整个消息体所占用的字节数的大小

· 4字节的魔数,是固定值,有MESSAGE_MAGIC_CODE和BLANK_MAGIC_CODE

· 4字节的CRC,是消息体的校验码,用于防止网络、硬件等故障导致数据与发送时不一样带来的问题

· 4字节的queueId,表示消息发到了哪个MessageQueue(逻辑上相当于kakka的partition)

· 4字节的flag,flag是创建Message对象时由生产者通过构造器设定的flag值

· 8字节的queueOffset,表示在queue中的偏移量

· 8字节的physicalPosition,表示在存储文件中的偏移量

· 4字节sysFlag,是生产者相关的信息标识,具体生产逻辑可以看相关代码

· 8字节消息创建时间

· 8字节消息生产者的host

· 8字节消息存储时间

· 8字节消息存储的机器的host

· 4字节表示重复消费次数

· 8字节消息事务相关偏移量

· 4字节表示消息体的长度

· 消息休,不是固定长度,和前面的4字节的消息体长度值相等

· 1字节表示topic的长度,因此topc的长度最多不能超过127个字节,超过的话存储会出错(有前置校验)

· Topic,存储topic,因为topic不是固定长度,所以这里所占的字节是不固定的,和前一个表示topic长度的字节的值相等

· 2字节properties的长度,properties是创建消息时添加到消息中的,因此,添加在消息中的poperties不能太多太大,所有的properties的kv对在拼接成string后,所占的字节数不能超过2^15-1

· Properties的内容,也不是固定长度,和前面的2字节properties长度的值相同

2 ConsumeQueue

一个ConsumeQueue表示一个topic的一个queue,类似于kafka的一个partition,但是rocketmq在消息存储上与kafka有着非常大的不同,RocketMQ的ConsumeQueue中不存储具体的消息,具体的消息由CommitLog存储,ConsumeQueue中只存储路由到该queue中的消息在CommitLog中的offset,消息的大小以及消息所属的tag的hash(tagCode),一共只占20个字节,整个数据包如下:

image.png

3 消息存储方式

前文已经描述过,RocketMQ的消息存储由CommitLog和ConsumeQueue两部分组成,其中CommitLog用于存储原始的消息,而ConsumeQueue用于存储投递到某一个queue中的消息的位置信息,消息的存储如下图所示:

image.png

消费者在读取消息时,先读取ConsumeQueue,再通过ConsumeQueue中的位置信息读取CommitLog,得到原始的消息。

4 消息存储与kafka的对比

Kafka中,每个partition有独立的消息存储,投递到每个partition的消息,存储在partition自己的存储文件中,示意图如下:

image.png

在消息的存储上,RocketMQ与Kafka的主要区别在于,RocketMQ将所有消息存储在同一个CommitLog中且ConsumeQueue中每个消息只存储20个字节的消息位置信息,而Kafka将每个partition的消息分开存储,这导致RocketMQ单个broker能支持更多的topic和partition。

因为在RocketMQ中,所有消息都存储在同一个文件中,这使得RocketMQ的消息存储是磁盘的顺序写,而kafka将消息按partition存储在不同的文件中,因此kafka在消息存储上是随机IO,磁盘的顺序IO要比随机IO快得多,顺序IO可以接近内存的速度。将partition的数量非常大时,kafka中的随机IO将非常多,这将导致kafka在所有topic的partition变大了之后broker性能会明显下降。

但是RocketMQ的ConsumeQueue也是随机IO,为何相比kafka能支持更多的partition呢,原因是RocketMQ通过MappedFile的方式读写ConsumeQueue,操作系统对内存映射文件有page cache而ConsumeQueue中的数据都非常小(只有20bytes),读写几乎都是page cache的操作,因此虽然是随机IO但效率也非常高。

5 源码阅读

RocketMQ中的相关源码在DefaultMessageStore类、CommitLog类和ConsumeQueue类中,其中DefaultMessageStore的内部类ReputMessageService会将存储到CommitLog中的消息写入到ConsumeQueue:

image.png

从doDispatch方法进去,依次进入调用链,在DefaultMessageStore类的内部类CommitLogDispatcherBuildConsumeQueue中,我们可以看到将消息的位置信息写入到ConsumeQueue中的相关代码:

image.png

而putMessagePositionInfo方法的实现就非常简单了,它先选出正确的MessageQueue,然后调用其方法写入数据:

image.png

最后附上ConsumeQueue中的关键代码片断,表示如何写入那20个字节的:

image.png

Long + int + long 一共20字节。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容