当前位置: 首页 > 科技观察

什么是零拷贝,Netty是如何实现的?

时间:2023-03-12 17:34:29 科技观察

作为一个高性能的网络通信框架,越来越受到互联网公司的关注和重视。最近面试过程中有小伙伴被问到Netty是如何做到零拷贝的?今天,我将与您交谈。我们先来看看什么是零拷贝?1、什么是零拷贝?在计算机中,完成数据传输,要么通过网络,要么通过本地磁盘。通常,一个完整的I/O交互过程分为两个阶段。首先复制到系统内核空间,由操作系统完成;然后复制到用户空间,由应用程序完成。具体交互过程如下图所示。那么什么是零拷贝?顾名思义,零拷贝是指“零”和“拷贝”两部分:“拷贝”:是指将数据从一个存储区域转移到另一个存储区域。“零”:表示次数为0,表示复制数据的次数为0。综合起来,“零复制”是指不需要将数据从一个存储区复制到另一个存储区。2.为什么需要零拷贝?零拷贝主要是指系统内核空间的内存与用户空间的内存直接关联映射,从而省去数据传输过程中的来回拷贝,即完成数据的数据拷贝数传输为0次。有这么一段代码,主要是从连接的socket中发送服务器主机磁盘中的文件。关键实现代码如下:while((n=read(diskfd,buf,BUF_SIZE))>0){write(sockfd,buf,n);}以上代码是传统IO写法,其执行过程为大致是这样的:首先,read()方法会循环读取磁盘中的数据到内核缓冲区,然后复制到用户缓冲区。然后,write()方法先将数据写入socketbuffer,最后写入网卡设备。因为传统IO在数据传输过程中拷贝次数过多,导致性能低下。为了减少副本数量,提高系统性能,出现了零拷贝设计。另外,零拷贝并不是说文件完全没有拷贝,只是减少了拷贝的次数。3、Netty中零拷贝的实现从流程图可以看出,传统的IO读写过程包括4次用户态和内核态的切换,即4次上下文切换和4次数据拷贝,其中两次是CPU副本和两个DMA副本。关于上下文切换和DMA复制,这里不再赘述,以后可以单独拍个视频详细介绍。想了解更多的朋友可以在评论区回复666。Netty中如何实现零拷贝?一共有三种方式(1)使用堆外内存,也叫直接内存。Netty使用DIRECTBUFFERS进行接收和发送,对应系统底层的mmap机制,直接使用堆外内存进行Socket读写,不需要对bytebuffer进行二次拷贝。(2)提供了组合Buffer对象,可以聚合多个ByteBuffer对象。用户只需像操作一个Buffer一样方便地操作合并后的Buffer,避免了传统的通过内存拷贝将几个小Buffer合并成一个大Buffer的方法。缓冲区,不需要做内存拷贝。(3)文件传输使用transferTo方法,直接使用NIO的sendfile机制,可以直接将文件缓冲区中的数据发送到目标Channel,避免了传统的循环写方式带来的内存拷贝问题。