零拷贝常用技术
上一次我们说了传统的IO操作是如何是实现的,最后引出了零拷贝技术,这次我们看看有那些零开拷贝技术.(如果不使用零拷贝技术,普通的IO操作在OS层面是如何执行的)
mmap+write零拷贝技术
mmap+write拷贝技术替换了传统的read+write技术,减少了一次CPU拷贝,mmap实际上Linux提供的一种内存映射技术,他把用户进程的一段虚拟地址映射到磁盘文件的地址.
因此使用mmap技术是为了把内核缓冲区的地址和用户缓冲区进行映射,从而使内核缓冲区地址和应用程序内存的地址进行共享,从而减少内核缓冲区到用户缓冲区的拷贝,如下图
上图表示,整个过程会有四次切换,和两次DMA拷贝,一次CPU拷贝,而mmap是针对大文件提高了I/O性能,但是对于小文件,可能会导致内存碎片的浪费
sendfile+DMA gather copy
sendfile系统调用,可以直接在内核空间进行拷贝,减少用户空间和内核空间的来回拷贝.
它将内核空间的读缓冲区(read buffer)中对应的数据描述信息(内存地址、地址偏移量)记录到相应的网络缓冲区( socket buffer)中,由 DMA 根据内存地址、地址偏移量将数据批量地从读缓冲区(read buffer)拷贝到网卡设备中。
这样 DMA 引擎直接利用 gather 操作将页缓存中数据打包发送到网络中即可,本质就是和虚拟内存映射的思路类似。
上图表示整个过程,发生两次切换,两次DMA拷贝
splice零拷贝技术
splice是sendfile+DMA gather copy 又一次提升,他直接在内核空间的读缓冲区和网络缓冲区建立了通道pipeline,减少两者之间的CPU拷贝
上图表示,整体上经历了两次切换,和两次DMA拷贝,0次cpu拷贝
我们常用的组件kafka就是用的sendfile+DMA gather copy技术,而我们的RocketMq使用的是mmap+write技术等等