协议封装:TCP 对比 Aeron/UDP
原始字节开销几乎不分伯仲,但行为上的差异却天壤之别。这正是将 TCP/IP 协议栈与 Aeron 基于 UDP 的协议栈进行对比时最核心的结论。
两套协议栈都运行在相同的以太网和 IP 层之上。它们在传输层开始分道扬镳,而这一分歧之处,正是你的尾延迟所在。
TCP/IP 协议栈
Section titled “TCP/IP 协议栈”每一个 TCP 分段都会在协议栈的各层被逐层包裹上报文头。
┌──────────────────────────────────────────────────────────────┐│ OSI 1: Physical — Cables, fibre, wires │├──────────┬───────────────────────────────────────┬───────────┤│ Header │ Ethernet Payload (46-1500 bytes MTU) │ CRC ││ 14 bytes │ │ 4 bytes │├──────────┼───────────────────────────────────────┤ OSI 2 ││ IP Hdr │ IP Data Array │ ││ 20 bytes │ │ OSI 3 │├──────────┼───────────────────────────────────────┤ ││ TCP Hdr │ TCP Data Array │ ││ 20 bytes │ │ OSI 4/5 │├──────────┼───────────────────────────────────────┤ ││ HTTP ? │ Application Data │ OSI 6&7 │└──────────┴───────────────────────────────────────┴───────────┘TCP 的开销计算
Section titled “TCP 的开销计算”以一个 1500 字节 MTU 的以太网帧为例:
- 以太网头:14 字节 + CRC:4 字节 = 18 字节
- IP 头:20 字节
- TCP 头:20 字节
- 总开销:58 字节 → 留给应用数据的约为 ~1442 字节
- 如果使用 HTTP,还要再加上 HTTP 报文头 → 可用载荷更少
Aeron/UDP 协议栈
Section titled “Aeron/UDP 协议栈”Aeron 保留了以太网和 IP 层,将 TCP 替换为 UDP,并用其自有的可靠性层取代了应用层协议。
┌──────────────────────────────────────────────────────────────┐│ OSI 1: Physical — Cables, fibre, wires │├──────────┬───────────────────────────────────────┬───────────┤│ Header │ Ethernet Payload (46-1500 bytes MTU) │ CRC ││ 14 bytes │ │ 4 bytes │├──────────┼───────────────────────────────────────┤ OSI 2 ││ IP Hdr │ IP Data Array │ ││ 20 bytes │ │ OSI 3 │├──────────┼───────────────────────────────────────┤ ││ UDP Hdr │ Aeron Message │ ││ 8 bytes │ │ OSI 4/5 │├──────────┼───────────────────────────────────────┤ ││ Aeron Hdr│ Application Data │ ││ 24 bytes │ │ OSI 6&7 │└──────────┴───────────────────────────────────────┴───────────┘开销对比:TCP 对比 Aeron/UDP
Section titled “开销对比:TCP 对比 Aeron/UDP”| 层 | TCP 协议栈 | Aeron/UDP 协议栈 |
|---|---|---|
| 以太网 | 18 字节 | 18 字节 |
| IP | 20 字节 | 20 字节 |
| 传输层 | TCP:20 字节 | UDP:8 字节 |
| 会话层/应用层 | HTTP:可变(数百字节) | Aeron:24 字节 |
| 总开销 | 58+ 字节(不含 HTTP) | 70 字节(含 Aeron 头) |
字节数相近,但这些字节为你换来的东西却大不相同。
- UDP 头为 8 字节,而 TCP 头为 20 字节 —— 每个数据包节省 12 字节。
- Aeron 增加了自有的 24 字节报文头 来实现可靠性(序列号、流 ID 等)。
- 没有 TCP 握手,没有 TCP 拥塞控制,没有 TCP 队头阻塞。
- Aeron 通过基于 NAK 的重传实现自有的可靠性 —— 在组播和高吞吐场景下更为高效。
这对调优为何重要
Section titled “这对调优为何重要”报文头字节对吞吐量几乎没有影响。UDP 相比 TCP 节省的 12 字节,再减去 Aeron 在自有报文头上多花的字节,相对于 1500 字节的帧而言不过是舍入误差。所以不要为了省下区区几个字节而选择 Aeron。
选择它,是为了尾延迟。TCP 的拥塞控制和严格按序交付才是真正的代价。它们在高负载下抬高 p99,并注入任何缓冲区调整都无法完全消除的抖动:
- 队头阻塞 —— 一个丢失的分段会让其后的每一个分段都被卡住,即便网络状况良好也会让 p99 飙升。
- 拥塞控制 —— TCP 会按照它自己的节奏限制发送方,从而压低吞吐量,并带来你并不想要的延迟。
- 握手 —— 建立连接会在第一个字节数据传输之前增加若干次往返。
Aeron 在 UDP 之上基于 NAK 的重传机制规避了上述三个问题。它自行掌控重传时机,且从不阻塞队头,从而使 p50 保持紧凑、p99 保持可预测。
关于 Aeron 的 NAK 协议、序列号和 term buffer 究竟如何承载这些字节,请参阅 The Aeron Files。本页面专注于协议栈对比。