4. 显式拥塞通知(ECN)原理:IP头ECN字段、ECN协商过程、ECN标记策略
4.1 从丢包信号到标记信号:ECN 的设计动机
传统 TCP 拥塞控制依赖丢包作为拥塞信号——交换机队列溢出后丢弃报文,接收端通过缺失序号感知丢包,进而触发发送端降速。这种“以丢包为代价”的反馈机制在数据中心场景中代价高昂:丢包不仅造成重传延迟(通常达微秒至毫秒级),还会引发 TCP 超时重传、吞吐坍塌,尤其对 RDMA 等无损网络而言,丢包更是不可接受的。
ECN(Explicit Congestion Notification,显式拥塞通知)的核心思想是:在队列深度达到阈值但尚未溢出时,由交换机在报文上打上“拥塞标记”,接收端将该标记反馈给发送端,发送端据此降速。这样,拥塞信号从“隐性的丢包”转变为“显式的标记”,避免了丢包本身带来的性能损伤。
4.2 IP 头中的 ECN 字段:两个比特的精细分工
ECN 复用 IP 头中 ToS(Type of Service)字节的最高两位,定义如下:
| ECT 码点 | CE 码点 | 二进制值 | 含义 | 说明 |
|---|---|---|---|---|
| Not-ECT | — | 00 | 不支持 ECN | 传统流量,交换机不做标记 |
| ECT(1) | — | 01 | 支持 ECN,传输能力 1 | 发送端支持 ECN |
| ECT(0) | — | 10 | 支持 ECN,传输能力 0 | 发送端支持 ECN(常用) |
| CE | CE | 11 | 拥塞经历 | 交换机检测到拥塞后标记 |
两个比特的语义组合非常精巧:前两位(ECT 码点)由发送端设置,用于声明“我支持 ECN”;后一种状态(CE)由中间交换机在拥塞时改写。接收端通过检查 IP 头中的 CE 位,即可判断报文是否经历了拥塞。
4.3 ECN 协商过程:端到端的完整闭环
ECN 的生效需要发送端、接收端和中间交换机三方配合,其协商过程贯穿 TCP 连接的建立和数据传输阶段:
- 能力协商(TCP 握手阶段):发送端在 SYN 报文中设置 ECE 标志和 CWR 标志,声明自己支持 ECN;接收端在 SYN-ACK 中回应 ECE 标志,确认双方都具备 ECN 能力。
- 数据发送(ECT 设置):协商成功后,发送端在 IP 头中设置 ECT(0) 或 ECT(1),表示“本报文支持 ECN 标记”。
- 拥塞标记(交换机动作):当交换机队列深度超过阈值(如 K 参数),且报文 IP 头为 ECT(0) 或 ECT(1) 时,交换机将其改写为 CE(11),然后正常转发。
- 拥塞反馈(接收端动作):接收端收到 CE 标记的报文后,在后续 TCP ACK 中设置 ECE 标志,向发送端反馈“网络发生了拥塞”。
- 降速响应(发送端动作):发送端收到带 ECE 的 ACK 后,将拥塞窗口减半(或按算法调整),并在下一个数据报文(或专用报文)中设置 CWR 标志,表示已执行降速。
sysctl net.ipv4.tcp_ecn 查看/启用 ECN 支持。值为 0 表示禁用,1 表示仅接受对端请求,2 表示主动请求启用。数据中心场景建议设置为 1 或 2。
4.4 ECN 标记策略:阈值与概率的权衡
交换机如何决定何时将 ECT 报文标记为 CE,是 ECN 性能的核心。常见策略有两种:
- 阈值标记(Threshold-based Marking):当队列瞬时长度超过固定阈值 K 时,对所有新到达的 ECT 报文打 CE 标记。实现简单,但容易造成标记突发,导致发送端窗口过激收缩。
- 概率标记(Probability-based Marking):当队列长度超过最低阈值后,按概率函数(如线性或二次函数)决定是否标记。标记概率随队列长度平滑增长,反馈更温和,但实现复杂度略高。
在 RoCEv2 无损网络中,DCQCN 采用基于瞬时队列长度的概率标记:当队列长度超过阈值 K 时,标记概率随超出程度线性增加。这种策略既能快速反馈拥塞,又避免了窗口的剧烈振荡。
4.5 案例:DCTCP 中的 ECN 标记与反馈
以数据中心经典算法 DCTCP 为例,其 ECN 工作流程如下:
发送端(DCTCP 发送方) 交换机 接收端
| | |
|---- IP头 ECT(0) 数据报文 ------------>| |
| |-- 队列深度 > K? --> 是 |
| |-- 改写为 CE(11) -------->|
| | |-- 收到 CE 报文
|<---------------- ACK (ECE=1) ------------------------------------|
|-- 计算拥塞因子 α = (1-g)×α + g×F --> F = CE标记报文数/总报文数 |
|-- 窗口调整:W = W × (1 - α/2) --------------------------------->|
DCTCP 的关键在于发送端不是简单地将窗口减半,而是根据 CE 标记报文的比例 F 动态计算拥塞因子 α,再以 W × (1 - α/2) 调整窗口。当网络轻度拥塞时(F 较小),窗口只小幅收缩;重度拥塞时(F 接近 1),窗口接近减半。这种精细的反馈机制使 DCTCP 能在高带宽利用率下保持极低队列延迟。
4.6 误区与复盘:ECN 部署中的典型问题
| 误区 | 后果 | 正确做法 |
|---|---|---|
| 交换机开启 ECN 但主机未启用 | 报文均为 Not-ECT,交换机无法标记,ECN 形同虚设 | 确认收发两端 tcp_ecn 均已启用 |
| 标记阈值 K 设置过大 | 队列溢出先于标记发生,ECN 退化为丢包反馈 | K 设为交换机缓冲区的 20%~30% |
| 忽略接收端反馈延迟 | CE 标记到发送端降速之间延迟过大,队列持续增长 | 确保 ACK 路径无拥塞,或使用优先 ACK 队列 |
| 所有流量一刀切启用 ECN | 对延迟敏感的小流和带宽敏感的大流采用相同标记策略 | 按流优先级或流量类型差异化配置 ECN 阈值 |
ss -tin 查看 TCP 连接的 ECN 状态),再逐步推广到生产网络。