零拷贝-笔记
1 几个重要的概念
1.1 用户空间和内核空间
操作系统的核心是内核,独立于普通的应用程序,可以访问受保护的内存空间,也有访问底层硬件设备的所有权限。为了保证用户进程不能直接操作内核 (kernel),保证内核的安全,操作系统将虚拟空间划
分为两部分,一部分为内核空间,一部分为用户空间。
1.2 IO两个流程
第一阶段:等待网络上的数据分组到达,然后被复制到内核的某个缓冲区。
第二阶段:把数据从内核缓冲区复制到应用程序缓冲区中。
2 传统的IO流
- 通过 DMA copy 数据从hard driver 拷贝到kernel buffer
- 通过 CPU copy 数据从kernel buffer 拷贝到 user buffer
- 通过 CPU copy 数据从 user buffer 拷贝到kernel buffer
- 通过 CPU copy 数据从 kernel buffer 拷贝到socket buffer
- 通过DMA copy 将socket buffer 中的数据发送出去
3 零拷贝(zero-copy)
3.1 零拷贝的概念
零拷贝主要的任务是避免CPU将数据从一块存储拷贝到另外一块存储,主要就是利用各种拷贝的技术,
避免让CPU做大量的数据拷贝任务,减少不必要的拷贝,或者说让别的组件来做这一类简单的数据传输,让CPU专注于别的任务。这样就可以让系统资源利用的更加有效。
如何减少数据拷贝的次数呢?减少用户空间到内核空间的拷贝 mmap 优化。
3.2 减少用户空间和内核空间的拷贝
3.3 直接传递文件描述(sendfile)
4 零拷贝的再次理解
1) 零拷贝是从操作系统⻆度来说的。因为内核缓冲区之前,没有数据的重复(只有kernel buffer 有一份数据)。
2)零拷贝不仅仅带来了更少的数据复制,还能带来其他的性能优势,例如:更少的上下文切换,更少的CPU缓存伪共享以及无CPU校验和计算。
5 mmap 和sendFile 的区别
- mmap 适合小数据量读写,sendFile适合大文件传输
- mmap 需要4次上下文切换、3次数据拷贝;sendFile 需要3次上下文切换、最少2次数据拷贝。
- sendFile 可以利用DMA⽅式,减少CPU拷贝,mmap 则不能(必须从内核拷贝到socket 缓冲区)。
在这个选择上:RocketMQ 在消费消息时,使用了mmap。kafka使用了sendFIle。
6 哪些地方会使用到零拷贝技术
场景:
文件较大,读写较慢,追求速度
JVM内存不够,不能加载太大的数据
内存宽带不够,即存在其他程序或线程存在大量的IO操作,导致带宽本来就小
技术:
Java的NIO
Netty
kafka