RocketMQ存储
2021-11-06 12:14:58 20 举报
关于RocketMQ的存储一些流程化图
作者其他创作
大纲/内容
4
key 02 - A
存储结构
ConsumerQueue - Queue 1
header
slot table
index linked List
key 02 - B
key 01 - B
1
异步刷盘
2
key 03 - B
消费组
3
queue逻辑队列中的数据结构
消息在被写入CommitLog时,会进行mlock加锁,达到顺序写的目的,
ConsumerQueue - Queue 3
key 03 - A
page cache / 4K
ConsumerQueue - Queue 2
MessageTagHashCode
CommitLog offset定位消息的具体位置
key 01 - A
CommitLog
同步刷盘
size
生产消息
RocketMQ Broker
相对于CommitLog的数据被ConsumerQueue组读取是随机的。
相关参考文章:https://www.jianshu.com/p/6d0c118c17dehttps://www.jianshu.com/p/771cce379994https://www.jianshu.com/p/35fcd6e0bc93
1. 采用MappedByteBuffer进行内存映射,一次只能映射1.5G~2G的文件到用户态的虚拟内存mmap的特点是不需要将文件中的数据先拷贝到内核缓冲区,而是可以直接将用户进程私有地址空间中的一块区域与文件对象建立映射关系,这样程序就好像可以直接从内存中完成对文件读、写操作一样。只有当缺页中断发生时,直接将文件从磁盘拷贝至用户态的进程空间内,只进行了一次数据拷贝。
PageCache是OS对文件的缓存,用于加速对文件的读写。一般来说,程序对文件进行顺序读写的速度几乎接近于内存的读写访问,这里的主要原因就是在于OS使用PageCache机制对读写访问操作进行了性能优化,将一部分的内存用作PageCache。(1)对于数据文件的读取,如果一次读取文件时出现未命中PageCache的情况,OS从物理磁盘上访问读取文件的同时,会顺序对其他相邻块的数据文件进行预读取(ps:顺序读入紧随其后的少数几个页面)。这样,只要下次访问的文件已经被加载至PageCache时,读取操作的速度基本等于访问内存。(2)对于数据文件的写入,OS会先写入至Cache内,随后通过异步的方式由pdflush内核线程将Cache内的数据刷盘至物理磁盘上。对于文件的顺序读写操作来说,读和写的区域都在OS的PageCache内,此时读写性能接近于内存。RocketMQ的大致做法是,将数据文件映射到OS的虚拟内存中(通过JDK NIO的MappedByteBuffer),写消息的时候首先写入PageCache,并通过异步刷盘的方式将消息批量的做持久化(同时也支持同步刷盘);订阅消费消息时(对CommitLog操作是随机读取),由于PageCache的局部性热点原理且整体情况下还是从旧到新的有序读,因此大部分情况下消息还是可以直接从Page Cache中读取,不会产生太多的缺页(Page Fault)中断而从磁盘读取。PageCache机制也不是完全无缺点的,当遇到OS进行脏页回写,内存回收,内存swap等情况时,就会引起较大的消息读写延迟。对于这些情况,RocketMQ采用了多种优化技术,比如内存预分配,文件预热,mlock系统调用等,来保证在最大可能地发挥PageCache机制优点的同时,尽可能地减少其缺点带来的消息读写延迟。
key hash
CommitLogOffset
TimeStamp
NextIndexOffset
0 条评论
下一页