【Netty】零拷贝(zero-copy)


很多更新的技术在宣传的时候,都会提到速度、性能这个指标,什么提升了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
  • 9
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

超级码里喵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值