【Netty】零拷贝(zero-copy)

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 【Netty】零拷贝(zero-copy),希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文


很多更新的技术在宣传的时候,都会提到速度、性能这个指标,什么提升了10倍,100倍啊,其中有一个技术点叫做zero-copy,也叫做零拷贝。

零拷贝核心优化点:就需要减少「用户态与内核态的上下文切换」和「内存拷贝」的次数。

1. 零拷贝技术实现

1.直接 I/O
2.mmap
3.sendfile

2. 传统读取IO流的操作

2.1 读操作

1、应用程序发起读数据操作,JVM会发起read()系统调用。
2、这时操作系统OS会进行一次上下文切换(把用户空间切换到内核空间)
3、通过磁盘控制器把数据copy到内核缓冲区中,这里的就发生了一次DMA Copy
4、然后内核将数据copy到用户空间的应用缓冲区中,发生了一次CPU Copy
5、read调用返回后,会再进行一次上下文切换(把内核空间切换到用户空间)

读操作发送两次数据拷贝、两次上下文的切换。

2.2 写操作

1、应用发起写操作,OS进行一次上下文切换(从用户空间切换为内核空间)
2、并且把数据copy到内核缓冲区Socket Buffer,做了一次CPU Copy
3、内核空间再把数据copy到磁盘或其他存储(网卡,进行网络传输),进行了DMA Copy
4、写入结束后返回,又从内核空间切换到用户空间
两次上下文切换 两次数据拷贝

也就是说 socket客户端与服务器端通讯可能会发生四次上下文切换 四次数据拷贝。

2.3 MMAP+write

read() 系统调用的过程中会把内核缓冲区的数据拷贝到用户的缓冲区里,于是为了减少这一步开销,我们可以用 mmap() 替换 read() 系统调用函数。
mmap() 系统调用函数会直接把内核缓冲区里的数据「映射」到用户空间,这样,操作系统内核与用户空间就不需要再进行任何的数据拷贝操作。
在这里插入图片描述
可以减少一次 内核空间拷贝数据到用户空间,该方案也不是最理想的零拷贝实现方案。

2.4 Sendfile

Linux内核 在2.1版本:
可以直接把内核缓冲区里的数据拷贝到 socket 缓冲区里,不再拷贝到用户态,这样就只有 2 次上下文切换,和 3 次数据拷贝 但是这还不是真正的零拷贝技术

Linux内核 在2.4版本:
sendfile() 系统调用的过程发生了点变化
MA 控制器就可以直接将内核缓存中的数据拷贝到网卡的缓冲区里,此过程不需要将数据从操作系统内核缓冲区拷贝到 socket 缓冲区中,这样就减少了一次数据拷贝;这就是所谓的零拷贝(Zero-copy)技术

因为我们没有在内存层面去拷贝数据,也就是说全程没有通过 CPU 来搬运数据,所有的数据都是通过 DMA 来进行传输的,总体来看,零拷贝技术可以把文件传输的性能提高至少一倍以上。
在这里插入图片描述

3. 零拷贝应用场景

  1. kafka
  2. Nginx
  3. Spark

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/131194.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!