RocketMQ学习笔记:零拷贝

这是本人学习的总结,主要学习资料如下

目录


1、零拷贝技术

1.1、什么是零拷贝

使用传统的IO,从硬盘读取数据然后发送到网络需要经过四个步骤。

  1. 通过DMA复制读取硬盘数据,复制到系统的内核缓冲区。
  2. 从内核缓冲区通过CPU将数据复制到应用程序缓冲区。这里涉及到内核态转用户态。
  3. 从应用程序缓冲区通过CPU复制数据到套接字缓冲区。这里涉及到用户态转内核态。
  4. 最后通过DMA从套接字缓冲区复制数据到网卡等网络设备。发送数据的事就交给网络设备。


DMA(Direct Memory Access)可以说是一个可以直接访问磁盘等硬件的设备,不过速度要比CPU要慢很多。

所以传统的IO有四次复制过程。零拷贝则是利用内存映射等技术,减少其中的一两个拷贝过程,大大提高效率。

1.2、mmap()

RocketMQ是通过mmap()内存映射技术来实现零拷贝。

mmap将磁盘上的文件位置和应用程序缓冲区做了一个一一对应的映射,使应用程序可以像读取应用程序缓冲区一样直接读取到磁盘的文件内容。

使用了mmap后就可以省去一次DMA的复制。变成下面的过程。

  1. 通过mmap复制数据到应用程序缓冲区。
  2. 从应用程序缓冲区通过CPU复制数据到套接字缓冲区。这里涉及到用户态转内核态。
  3. 最后通过DMA从套接字缓冲区复制数据到网卡等网络设备。发送数据的事就交给网络设备。

1.3、Java中的零拷贝

Java中可以通过MappedByteBuffer来实现mmap,但是这种方式一次最多只能映射1.5 ~ 2G的文件,这也是RocketMQ的单个CommitLog文件默认是1G的原因。

java 复制代码
File file = new File(path);
// 通过Channenl进行内存空间和磁盘空间的映射
FileChannel fileChannel = new RandomAccessFile(file, "rw").getChannel();
// 该Buffer就是映射空间,可以看成是磁盘和内存共享的
MappedByteBuffer map = fileChannel.map(FileChannel.MapMode.READ_WRITE, 0, 1024);
// 写内容
mmap.put("Content".getBytes());
// 写内容到磁盘
mmap.flip();
byte[] bb = new byte[4];
//读取数据
mmap.get(bb, 0, 4);
// 解除mmap
unmap(mmap);
相关推荐
泽克13 小时前
3.6 消防工程施工技术
笔记
炽烈小老头13 小时前
【每天学习一点算法 2026/04/30】寻找重复数
学习·算法
handler0113 小时前
算法:图的基本概念
c语言·开发语言·c++·笔记·算法·图论
之歆13 小时前
Day05_CSS完整博客笔记(上)
前端·css·笔记
YJlio13 小时前
《Windows Internals》10.5.1 ETW 概述:看懂 Windows 的“事件高速公路”
java·windows·笔记·stm32·嵌入式硬件·学习·eclipse
木木_王13 小时前
嵌入式Linux学习 | 数据结构 (Day03)顺序表与单链表 超详细解析(含 C 语言实现 + 作业 + 避坑指南)
linux·c语言·数据结构·学习
阿Y加油吧13 小时前
二刷 LeetCode:198. 打家劫舍 & 279. 完全平方数 复盘笔记
笔记·算法·leetcode
知识分享小能手14 小时前
R语言入门学习教程,从入门到精通,R语言层次关系数据可视化(7)
学习·信息可视化·r语言
承渊政道14 小时前
【动态规划算法】(子序列问题解题框架与典型案例)
数据结构·c++·学习·算法·leetcode·macos·动态规划
阿Y加油吧14 小时前
二刷 LeetCode:215. 数组中的第 K 个最大元素 & 347. 前 K 个高频元素 复盘笔记
笔记·leetcode·排序算法