RocketMQ消息存储(一) - mmap零拷贝

RocketMQ消息存储(一) - mmap零拷贝(前置篇)

从本篇开始研究Broker 对文件的存储, 这些文件分为三类 (CommitLog , ConsumeQueue , IndexFile) 。

而在分析文件存储的源码之前, 我们要先了解一个重要的前置知识: 零拷贝IO 技术.

下面是针对不同的开源MQ总结的底层使用的IO方式:

MQ read/write
RocketMQ mmap/mmap (默认,可通过修改配置,配置成FileChannel,原因是作者想避免PageCache的锁竞争,通过两层架构实现读写分离)
Kafka record记录基于sendfile/sendfile index基于mmap/mmap
ActiveMQ RandomAccessFile/RandomAccessFile

1. 基本概念

我们需要先弄清楚, 物理内存与虚拟内存之间的关系, 以及虚拟内存下 用户空间与内核空间的关系, 弄清楚这些概念后对我们去理解 零拷贝 就非常的简单。

下面时我从 网上荡下来的一张图片:

这个图片我认为 非常清晰的能够体现出 上述我说的关系。

  • 物理内存: 就是实际上计算机真实的内存大小。

  • 虚拟内存:为了解决多进程出现同时操作同一物理内存地址的现象,于是就抽象虚拟内存。

  • 用户空间/内核空间: 为了系统安全性考虑,用户进程不能直接操作底层内核,因此就把 虚拟内存 又划分出了 用户空间 、内核空间两部分。

  • 映射:

    img

    上面这一张图是 虚拟内存 映射到 物理内存。

    多进程的虚拟内存中的内核空间是共享的,都映射在物理内存的系统内核空间上。 而虚拟内存中的用户空间 则被映射到了不同的物理内存区域。

2. mmap内存映射原理分析

以上我们清楚了 物理内存与虚拟内存之间的映射关系, 它们之间实际上是通过 页表和MMU的方式来实现 地址之间的转换映射。

而本小节所说的 mmap内存映射 中的 映射 主要指的是 硬盘上文件的位置 与 **虚拟内存地址空间 **的 一 一对应,这种关系是逻辑上的概念。

注意: 在mmap的内存映射过程中, 并没有实际的数据拷贝,文件也并没有载入物理内存,只是逻辑上与虚拟内存形成了映射关系。

img

过程1: 实际上就是mmap内存映射, 只是建立了 文件 与 虚拟内存之间 逻辑上的映射关系。

假设 这时候 需要 读取文件上的一段数据, 因为 虚拟内存 与 文件的位置 已经建立了逻辑上的映射关系, 一次直接通过 虚拟内存来从物理内存上获取数据。

过程2:通过虚拟内存地址与物理内存地址的转换, 能够访问到 目标那块地址 上有无数据。 若没有数据,则说明文件没有加载到物理内存中,因此会产生缺页中断。

过程3:产生了缺页中断,因此就需要物理内存的内核去完成数据拷贝。 也就是将文件的数据 加载到 对应的物理内存地址中。

过程4:若在加载数据到物理内存的过程中, 物理内存的空间不够用, 因此就会产生 swap 交换, 从物理内存上腾出一部分空间给文件数据使用。

posted @   s686编程传  阅读(514)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
历史上的今天:
2021-03-09 SpringMVC 六 (视图解析器)
点击右上角即可分享
微信分享提示