Netty学习笔记(三)零拷贝原理剖析及其应用实例

Netty学习笔记(三)零拷贝原理剖析及其应用实例

传统网络io通信(读写)过程

先来理解当我们想从某台机器将一份数据(比如一个文件)通过网络传输到另外一台机器(网络服务器将存储在文件中的数据通过网络传输到客户端)时,传统网络io通信(读写)过程:

File file = new File("test.txt");
RandomAccessFile raf = new RandomAccessFile(file, "rw");
byte[] arr = new byte[(int) file.length()];
raf.read(arr);
//
Socket socket = new ServerSocket(1234).accept();
socket.getOutputStream().write(arr);

1.JVM向系统发送read()系统调用触发上下文切换,从用户态切换到内核态。
2.系统会将硬盘上的数据先通过DMA(直接内存拷贝,不使用CPU)拷贝到内核buffer中。
3.内核buffer再将数据经过CPU拷贝,拷贝到用户buffer。read()系统调用返回,并从内核态切换回用户态。
3.数据在用户buffer中进行修改等操作(此时已将数据读取到)
4.JVM向系统发送write()请求,开始将操作完之后用户buffer中的数据写出,触发上下文切换,从用户态切换到内核态。
5.将用户buffer中的数据通过CPU拷贝到socketBuffer中
6.最后通过socketBuffer将数据进行DMA拷贝到协议栈(硬件buffer如网卡等),write()系统调用返回,并从内核态切换回用户态。
时序图:

整个过程经过4次拷贝4次状态切换

零拷贝是网络编程的关键,关于零拷贝提供了两种方式分别是:mmap+write方式,sendfile方式

mmap优化

mmap 通过内存映射,将文件映射到内核缓冲区,同时,用户空间可以共享内核空间的数据。这样,在进行网络传输时,就可以减少内核空间到用户控件的拷贝次数。如图:

整个过程3次拷贝4次状态切换

sendFile

Linux 2.1 版本 提供了 sendFile 函数,其基本原理如下:数据根本不经过用户态,直接从内核缓冲区进入到 Socket Buffer,同时,由于和用户态完全无关,就减少了一次上下文切换

整个过程经过3次拷贝3次状态切换
但其中还是存在CPU拷贝,所以还并不是真正意义上的零拷贝(零拷贝从操作系统角度,没有cpu 拷贝)

Linux 在 2.4 版本中修改了sendFile

避免了从内核缓冲区拷贝到 Socket buffer 的操作,直接拷贝到协议栈(但还是有少量描述性信息通过CPU拷贝从kernel buffer 拷贝到-> socket buffer,但消耗很低可以忽略不计,所以认为其实现了零拷贝),从而再一次减少了数据拷贝。

整个过程可以认为是经过2次拷贝3次状态切换(实际还有一次拷贝是kernel buffer 会将一些描述类信息拷贝到-> socket buffer)

所谓零拷贝

1.我们说的零拷贝,是从操作系统的角度来说的。因为内核缓冲区之间,没有数据是重复的(只有 kernel buffer 有一份数据)(也可以理解整个读写过程中为没有CPU内存拷贝)。
2.零拷贝不仅仅带来更少的数据复制,还能带来其他的性能优势,例如更少的上下文切换,更少的 CPU 缓存伪共享以及无 CPU 校验和计算。

mmap 和 sendFile 的区别

1.mmap 适合小数据量读写,sendFile 适合大文件传输。
2.mmap 需要 4 次上下文切换,3 次数据拷贝;sendFile 需要 3 次上下文切换,最少 2 次数据拷贝。
3.sendFile 可以利用 DMA 方式,减少 CPU 拷贝,mmap 则不能(必须从内核拷贝到 Socket 缓冲区)。
传统网络io通信(读写)过程代码示例:

package com.ywb.javaroad.netty.nio.zerocopy;

import java.io.DataInputStream
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值