通过网络传输数据流程
第一步:read系统调用,通过DMA调用,从磁盘/存储设备copy文件到kernel缓冲空间,发生一次用户态-内核态上下文切换
第二步:read系统调用返回后,发生一次从内核态-用户态的上下文切换,数据从内核缓冲空间复制到用户地址缓冲区(通过CPU copy);
第三步:发生write系统调用,把数据从用户地址空间复制到内核地址空间缓冲区,此次的内核缓冲区和socket关联,再次发生一次用户态-内核态上下文切换(CPU copy);
第四步:write系统调用返回,异步的发送数据到网络设备(DMA),发生一次内核态-用户态上下文切换;
零拷贝
Zero-Copy
- 基于mmap
- 基于sendfile
区别:
- mmap适用于小文件传输;sendfile基于大文件传输,只能使用BIO,不能使用NIO
- mmap需要进行4次上下文切换,3次数据复制;sendfile经过3次上下文切换,最少2次数据复制
- sendfile可以利用DMA(Directly Memory Access);mmap则必须由内核copy到Socket缓冲区
使用案例:
kafka基于sendfile进行零拷贝(使用transferTo和transferFrom);
RocketMq基于mmap进行零拷贝,因为有小文件传输的需求;