零拷贝技术sendfile

网友投稿 578 2022-05-29

愿打开此篇对你有所帮助。

(图片来源网络)

@[toc]

曾经的 I/O 过程

弊端分析

可以看到,整个数据的传输过程,都要需要 CPU 亲自参与搬运数据的过程,而且这个过程,CPU 是不能做其他事情的。

解决方案

DMA 技术,也就是直接内存访问(Direct Memory Access) 技术。

在进行 I/O 设备和内存的数据传输的时候,数据搬运的工作全部交给 DMA 控制器,而 CPU 不再参与任何与数据搬运相关的事情,这样 CPU 就可以去处理别的事务。

弊端

四次上下文切换 + 四次拷贝。

我就传一份数据,整这么麻烦。

解决方案

在 Linux 内核版本 2.1 中,提供了一个专门发送文件的系统调用函数 sendfile(),函数形式如下:

#include ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);

零拷贝技术 与 sendfile

如果网卡支持 SG-DMA(The Scatter-Gather Direct Memory Access)技术,我们可以进一步减少通过 CPU 把内核缓冲区里的数据拷贝到 socket 缓冲区的过程。

检查一下,这一步我来讲,不要去百度了,一个抄一个,都没有亲测,看着就烦。

注意看你的网卡叫什么名字,不一定就 eth0.

于是,从 Linux 内核 2.4 版本开始起,对于支持网卡支持 SG-DMA 技术的情况下, sendfile() 系统调用的过程发生了点变化。

这就是所谓的零拷贝(Zero-copy)技术,因为我们没有在内存层面去拷贝数据,也就是说全程没有通过 CPU 来搬运数据,所有的数据都是通过 DMA 来进行传输的。

现成应用场景

1、卡夫卡

2、nginx(我就是从nginx源码里看到sendfile,于是写了这一篇)

危险!!!

在传输大文件(GB 级别的文件)的时候,PageCache 会不起作用,那就白白浪费 DMA 多做的一次数据拷贝,造成性能的降低,即使使用了 PageCache 的零拷贝也会损失性能。

由于文件太大,可能某些部分的文件数据被再次访问的概率比较低,这样就会带来 2 个问题:

PageCache 由于长时间被大文件占据,其他「热点」的小文件可能就无法充分使用到 PageCache,于是这样磁盘读写的性能就会下降了; PageCache 中的大文件数据,由于没有享受到缓存带来的好处,但却耗费 DMA 多拷贝到 PageCache 一次;

所以,针对大文件的传输,不应该使用 PageCache,也就是说不应该使用零拷贝技术,因为可能由于 PageCache 被大文件占据,而导致「热点」小文件无法利用到 PageCache,这样在高并发的环境下,会带来严重的性能问题。

解决方案

在高并发的场景下,针对大文件的传输的方式,应该使用「异步 I/O + 直接 I/O」来替代零拷贝技术。

如果不是高并发的大文件IO,我选择临时起个线程。

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:缓存特征
下一篇:纸质文档管理助力档案资源价值发挥
相关文章