RocketMQ存储系统概要设计和源码解读
普遍消息存储技术的选型
- 分布式KV存储
- NewSQL存储:TiDB
- RocketMQ:所有的message存储在一个log里,不区分topic-queue
- kafka:一个log文件存储单个topic-queue
文件系统:RocketMQ,kafka,RabbitMQ
RocketMQ实现消息存储
MappedFile(映射文件)
CommitLog
下图为CommitLog结构:MappedFile(真实的映射文件)组成MappedQueue构成

存储消息CommitLog.putMessage()
- 获取最近一个CommitLog的内存映射文件(零拷贝)
- MappedFileQueue.getLastMappedFile():从其维护的列表中获取最后一个,因为之前的都已经写满了
- MappedFileQueue.load():构建一个MappedFile,加入到列表中
- 如果最近的CommitLog文件写满了或者broker刚启动,mappedfile是空的,创建一个新的
- MappedFileQueue.getLastMappedFile(create:true)
- 计算要创建的CommitLog的起始偏移量(即映射文件的名)
- allocateMappedFileService.putRequestAndReturnMappedFile()创建两个映射文件,但其实只要创建好第一个就返回了;
- 两种创建MappedFile方式(内存映射):堆外内存池,直接创建TODO
- 创建好后,对当前映射文件进行预热MappedFile.warmMappedFile:
- 对当前映射文件的每个内存页写入一个字节ByteBuffer,当刷盘策略为同步刷盘时,执行强制刷盘,每修改pages个分页刷一次盘;
- 因为对每个Mappedfile写入假字节的时候是通过循环的形式,而写入次数为MappedFile.size(1024M) / pagesize(4k),这样占有CPU的时间太久,所以线程会主动休眠,进入就绪状态,释放CPU
- MappedFile.mlock()将当前映射文件全部的地址空间锁定在物理存储中,防止被交换到swap空间
- 把broker内部的这个message刷新到Mappedfile的内存中mappedFile.appendMessage(msg, this.appendMessageCallback),有以下两种方式
- 直接将数据写到映射文件字节缓冲区mappedByteBuffer,后mappedByteBuffer.flush()
- 先写到内存字节缓冲区writeBuffer,再从writeBuffer提交commit到文件通道FileChannel,后FileChannel.flush()
- 刷盘:handleDiskFlush()
- 同步刷盘GroupCommitService:将刷盘请求放入执行线程维护的请求队列中,超时时间内等待执行
- 异步刷盘CommitRealTimeService/FlushCommitLogService:TODO
- 主从同步:handleHA()
- sync_master:HAService将刷盘请求放入GroupTransferService维护的写请求列表中
下图为CommitLog存储消息的流程:

ConsumerQueue/Index
是消息存储的索引文件:内存存储以topic(目录)/队列id(目录)/MappedFile.....
从CommitLog中拿到message
CommitLog写入message的时候,异步构建consumerqueue存储消息索引提供消费者消费
问题:
当topic数量增多时,kafka的单个broker的TPS降低了1个数量级,而RocketMQ在海量topic的场景下,依然保持较高的TPS?
CommitLog的”随机读”对性能的影响
RocketMQ存储系统概要设计和源码解读的更多相关文章
- 《Netty5.0架构剖析和源码解读》【PDF】下载
<Netty5.0架构剖析和源码解读>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062545 内容简介 Netty 是个异步的 ...
- 图像分割之(四)OpenCV的GrabCut函数使用和源码解读
图像分割之(四)OpenCV的GrabCut函数使用和源码解读 分类: 图像处理 计算机视觉 2013-01-23 ...
- Mybatis(四):MyBatis核心组件介绍原理解析和源码解读
Mybatis核心成员 Configuration MyBatis所有的配置信息都保存在Configuration对象之中,配置文件中的大部分配置都会存储到该类中 SqlSession ...
- Selenium系列(十) - 针对Select下拉框的操作和源码解读
如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...
- Selenium系列(21) - Cookie操作和源码解读
如果你还想从头学起Selenium,可以看看这个系列的文章哦! https://www.cnblogs.com/poloyy/category/1680176.html 其次,如果你不懂前端基础知识, ...
- tomcat架构分析和源码解读
最近在看<深入分析java web技术内幕>,书中讲解了一部分tomcat的相关知识,我也去查看了一些源码,看了大神们写的代码,我才知道自己就像在做加减乘除一样,这是不行的.还有好多包和类 ...
- python 微信跳一跳和源码解读
刚好周末,想研究一下前阵子很火的微信跳一跳 下面进入正文. 本文适用对象为WIN10系统,安卓用户.目的在于让丝毫没有接触过Python的小伙伴都能成功运行,如果你恰好是这样的对象,那么跟着我开始操作 ...
- [图像分割] OpenCV 的 GrabCut 函数使用和源码解读
转自 zouxy09 GrabCut 原理参考这里,以下为 GrabCut 源码: ——看别人写的好的代码也很享受,干净利落,有些处理的细节也学习一下. /*M//////////////////// ...
- http-proxy-middleware使用方法和实现原理(源码解读)
本文主要讲http-proxy-middleware用法和实现原理. 一 简介 http-proxy-middleware用于后台将请求转发给其它服务器. 例如:我们当前主机A为http://loca ...
随机推荐
- 【lucene】一个简单的招聘网站的建立
1.建立索引库: 核心代码如下 package com.tabchanj.job.index; import java.util.ArrayList; import java.util.HashMap ...
- 代码调试console对象的花式玩法
转自阮一峰http://www.ruanyifeng.com/home.html console.log(),console.info(),console.debug() console.log方法用 ...
- HTML 5的革新之一:语义化标签一节元素标签。
摘至于:<HTML 5的革新——语义化标签(一)> HTML 5的革新之一:语义化标签一节元素标签. 在HTML 5出来之前,我们用div来表示页面章节,但是这些div都没有实际意义.(即 ...
- 小P的架构生活(下)
小L强烈建议团队使用微服务,并极力推荐了前公司用的一套分布式事务解决方案. 小P经过反复思考查证并做了大量的尝试后,辨证地对微服务架构做了如下分析: 为什么要用微服务,微服务带来了哪些好处? 1.减少 ...
- Seeker:一款可获取高精度地理和设备信息的工具分析
Seeker是一款可以获取高精度地理和设备信息的工具.其利用HTML5,Javascript,JQuery和PHP来抓取设备信息,以及Geolocation接口实现对设备高精度地理位置的获取. See ...
- unicode 和utf-8,GBK编码
说到编码,得先从ASCII编码讲起.ASCII编码是由美国人发明,美国的字符不超过255个,所以ASCII编码使用了8bit 即一个字节来存储字符.由于汉字的数量远超255个,所以中国自己发明了一个G ...
- MySQL配置文件my.cnf中文详解
#BEGIN CONFIG INFO #DESCR: 4GB RAM, 只使用InnoDB, ACID, 少量的连接, 队列负载大 #TYPE: SYSTEM #END CONFIG INFO # # ...
- deep_learning_Function_LSTM_dynamic_rnn
一. tf.nn.dynamic_rnn的输出 tf.nn.dynamic_rnn的输入参数如下 tf.nn.dynamic_rnn( cell, inputs, sequence_ ...
- tornada-数据库
数据库 torndb安装 连接初始化 执行语句 execute execute_rowcount 查询语句 get query 与Django框架相比,Tornado没有自带ORM,对于数据库需要自己 ...
- (转)shell中括号的特殊用法 linux if多条件判断
一. bash [ ] 单双括号 基本要素: Ø [ ] 两个符号左右都要有空格分隔 Ø 内部操作符与操作变量之间要有空格:如 [ “a” = “b” ] Ø 字符串比较中,&g ...