两个主机通过以太网通信的数据复制过程 (Opus 4.6输出)
在传统网络通信中,数据从发送方应用到接收方应用,会经历多次数据复制(Data Copy),这是网络性能的一个重要瓶颈。
发送端流程
-
应用程序缓冲区 → 内核协议栈缓冲区(第1次复制)
- 应用调用
send()/write(),数据从用户空间拷贝到内核的 Socket 缓冲区(sk_buff) - 涉及用户态 → 内核态的上下文切换
- 应用调用
-
协议栈处理
- TCP/IP 各层添加头部(TCP头、IP头、以太网帧头)
- 数据可能在协议栈内部有额外的缓冲区操作
-
内核缓冲区 → 网卡(NIC)缓冲区(第2次复制)
- 通过 DMA(直接内存访问)将数据从内核内存复制到网卡的发送缓冲区
- 网卡将数据转为电信号/光信号发送到以太网
网络传输
- 数据以以太网帧的形式在物理介质上传输
- 可能经过交换机等设备的存储转发(又是一次复制)
接收端流程
-
网卡缓冲区 → 内核协议栈缓冲区(第3次复制)
- 网卡接收数据,通过 DMA 写入内核的环形缓冲区(Ring Buffer)
- 触发中断/NAPI 轮询,协议栈逐层解封装
-
内核协议栈缓冲区 → 应用程序缓冲区(第4次复制)
- 应用调用
recv()/read(),数据从内核 Socket 缓冲区拷贝到用户空间 - 再次涉及内核态 → 用户态切换
- 应用调用
总结
| 复制次数 | 从 | 到 | 说明 |
|---|---|---|---|
| 第1次 | 用户空间 | 内核空间 | send() 系统调用 |
| 第2次 | 内核空间 | 网卡 | DMA 传输 |
| 第3次 | 网卡 | 内核空间 | DMA 传输 |
| 第4次 | 内核空间 | 用户空间 | recv() 系统调用 |
总共约 4次数据复制 + 4次上下文切换(发送和接收各2次)
优化技术
- 零拷贝(Zero-Copy):如
sendfile()、mmap(),减少用户态与内核态之间的复制 - DPDK / RDMA:绕过内核协议栈,直接在用户空间操作网卡,大幅减少复制次数
- XDP(eXpress Data Path):在网卡驱动层直接处理数据包
这些多次复制是传统网络 I/O 性能受限的主要原因之一。