深入浅出零拷贝及其应用
零拷贝是一种优化技术,旨在减少数据在内存之间的拷贝次数,从而提高数据传输的效率和性能。在传统的数据传输过程中,数据需要从一个内存区域拷贝到另一个内存区域,再由操作系统将数据传输给目标应用程序。这意味着在数据的传输过程中,会涉及到多次内存拷贝操作,会消耗CPU的计算资源和内存带宽。
它有着很多应用,如网络数据传输,文件传输,数据库操作,多媒体处理,本文主要讲述了老师提及的一些应用。
传统文件传输过程
在小明通过网络传输发送消息给小明朋友的过程中,操作系统视角为:
read(file, tmp_buf,len);
// 从磁盘读取文件
write(socket, tmp_buf,len);
// 通过网络协议发送给客户端
Linux文件传输过程
- 发生了4次用户态与内核态的上下文切换
- 发生了4次数据拷贝 在上下文切换中,为了区分用户空间和内核空间,需要隔离操作系统程序和应用程序。
CPU拷贝
内核空间不能直接使用用户空间的数据:
- 内核不能信任任何用户空间的指针
- 稳定性大大增强但效率却降低了
将数据分别存储在内外的各个操作都是为了内核在一个安全稳定的情况下运行。
零拷贝的实现方式
零拷贝并不是0次拷贝数据,而是:
- 减少用户空间和内核空间之间的 CPU 拷贝次数
- 减少上下切换次数
介绍零拷贝的多种实现方式:
- 方案一:mmap + write
- 方案二:sendfile
- 方案三:sendfile + gather
- 方案四:splice
零拷贝的应用
Kafka性能优化点1:顺序读写
- producer 每次会追加写入到 partition
- consumer 每次消费的时候,根据 offset进行顺序读取
- 批量刷盘
Kafka性能优化点2:页缓存技术
- 利用linux 的page cache 技术
- 异步落盘,减少磁盘V/0 次数,通过 Replication 机制去解决数据丢失的问题页缓存技术
Kafka性能优化点3:零拷贝之mmap
Kafka性能优化点4:零拷贝之sendfile
- consumer 不需要对数据进行修改,可以采用零拷贝方式
- 对比传统read0 + write0,节省了2次cpu拷贝、2次上下文切换
对于RocketMQ,它通过mmap优化,通过文件预热的方式来解决缺页的问题。
总结与反思
学习零拷贝知识后,我对这项技术有了更深入的了解和反思,它可以提高数据传输效率,直接将数据从源地址传输到目标地址,减少了数据传输的开销。这样可以提高数据传输的效率,减少了不必要的CPU和内存资源消耗。