再谈QMQ与RocketMQ存储结构

<meta charset="utf-8">

之前做组内分享的准备的时候,我简单的写了一些RocketMQ与QMQ存储结构上的差异(https://www.jianshu.com/p/c2e2e9deb699),当时写的不是很详细,也存在一些不太准确的表述。我想重新用一篇文章,再理一理这里边的差异。

先讲更广为人知的RocketMQ,我先贴一张基础的存储结构

3.png

RocketMQ存储结构可以概括为三大部分:CommitLog,ConsumerQueue和IndexFile。

CommitLog是所有消息的顺序存储文件,broker收到的消息无脑往里边append。文件位于${ROCKET_HOME}/store/commitlog目录下,每个文件默认大小1G,超过就新建一个。所以commitLog并不是一个单一文件,而是一组文件的统称,文件名就是该文件的第一个偏移量。

在RocketMQ的源码中,commitlog目录对应的逻辑对象叫做MappedFileQueue,而具体的以起始偏移量命名的文件对应的逻辑对象叫做MappedFile。在消息写入commitlog文件之前,线程会先申请锁,因此消息写入commitlog的串行的。

ConsumerQueue众所周知,是commitlog的索引文件,根据topic来对消息区分存储,当然为了节约空间,ConsumerQueue文件里并不会存储消息的具体内容,从图中我们可以看到,commitlog在消息写入之后,由专门的线程产生消息转发任务,同步到ConsumerQueue中的只有commitlog offset,size,tag hashcode这三个信息。ConsumerQueue文件并不是像commitLog一样文件直接堆放在一起,而是在consumerQueue目录下,根据topic/queueId,再分了两层目录,提升了检索的效率。

IndexFile顾名思义就是一个索引文件,保存了消息的key值+消息在commitlog中的偏移量的键值对,便于通过消息的Key直接检索到消息的内容。IndexFile由三个部分组成,分别是总长为固定40个字节的IndexHeader,500w个Hash槽,还有2000w个Index条目,hash槽可以理解为HashMap中的数组,而index条目是用来解决hash冲突的,可以理解为Java HashMap中的链表。

总结来说,commitlog是一个大仓库,完成基本的存储,consumerQueue是针对消费者而设计的,而IndexFile是为了检索而设计的,侧重点不同。

CommitLog在构建ConsumerQueue是通过ReputMessageService异步实现的。从buffer中一条一条的读消息,读到以后根据消息的属性获取对应的ConsumerQueue文件,然后写进去。也就是说,从commitLog中读出来的消息就自己带了queueId,这样也比较好理解,consumerQueue由消息发送方指定的话,才有可能实现顺序消息。

说完了RocketQMQ的存储设计,再来聊聊QMQ的。QMQ的存储设计借鉴了RocketMQ和Kafka,并在他们的基础上做了自己的一些优化。

QMQ有类似于RocketMQ的commitlog的存储结构,叫messageLog,也是用来顺序存储消息的。每个文件的大小也是1G,基本的属性和RocketMQ都一致。

消息在写入messageLog后,起一个异步线程构建一个数据结构叫smt,全称为sorted messages table,顾名思义,这个smt不是对标ConsumerQueue的,它把所有的消息重新排序,按照subject排在一起。subject就是RocketMQ里的topic。这么做是为了在消息堆积时,提高page cache的命中率,使得消息消费时减少磁盘的IO。同时,smt是专门用来读的,等于对messageLog做了一个读写分离。这么做还有一个好处,就是消息内容在回写完smt之后,就可以将messageLog中的消息删除,节约了messageLog的磁盘占用,常规情况下messageLog就不会承担太多的消息存储,可以直接上SSD,提升消息写的IO性能。

consumerLog,将smt中排序好的消息,根据subject分发到各个文件里。文件中存储的是消息在smt中的索引。smt与consumerLog的内容写入是一起进行的。

pullLog文件是消费者的消费记录文件,以subject+consumerGroup+consumerId为维度,保留了每一个消费者的历史消费记录,这样可以在消费者重启之后快速定位到之前消费的位置。

4.png

其实可以理解为,consumer log + pull log相当于替代了RocketMQ中的COnsumerQueue的作用,将其做了一个拆分。我们知道在系统架构中,加一个中间层的好处和缺点都是很明显的,好处就是动态扩展会更加的灵活,耦合性会更加的低。同时,文件多了效率自然也就会收到影响,步骤越多 出错的机率越高。

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