一、现象与背景:吞吐满格,但 P99 抖到 480ms
在数据中心内网链路中,我们曾遇到一个经典 bufferbloat 案例:
- 环境:双口 25G 上联,白天高峰时段链路利用率爬到 85%~92%;
- 症状:业务 P99 从早上的 5ms 在 2 小时内缓慢爬到 40ms 上下,不抖、不断,丢包率 0;
- 干扰项:ping(64B)RTT 全程 5.1~5.3ms 纹丝不动;iperf3 单向 15min 带宽测试能跑满 24G+——这两个「经典体检项」全绿,但业务已经疼了 2 小时;
- 事后对账:把 1024B 以上的合成探测和 64B 的 RTT 差拉出来看,P99 劣化开始之前 ~15 分钟,大小包 RTT 差已经从 <0.5ms 爬到 2~3ms——但这个数据是我复盘时才补采的,当时没有把它当指标。
二、原理与根因:瓶颈不在链路,在发送端的队列
根因一句话:批量同步把链路打满后,发送侧内核的发送队列(以及交换机出端口队列)开始无限制地堆积,排队时间全部折算成了 RTT。
机制拆开看:
- TCP 的发送窗口是「越多越好」的:拥塞窗口(cwnd)只会在丢包或 RTT 增大时收缩。只要不丢包,cwnd 就一路涨,把对端接收缓冲和中间设备队列塞到最大。
- 队列延迟 = 队列里的字节数 ÷ 链路速率。10Gbps 链路,只要队列里堆了 6MB 数据,排队延迟就是
6MB / 10Gbps ≈ 4.8ms;堆到 60MB 就是 48ms;我们实测峰值队列深度到了 550MB 量级,对应排队延迟 440ms+,和 P99 完全对得上。 - 为什么丢包是 0:因为队列「够长」,包只是排队、还没溢出,所以没有任何一个包被丢。丢包是队列的「上限保护」,不是「延迟信号」——等到丢包发生,延迟早就爆表了。
这就是 bufferbloat 的反直觉核心:「不丢包」恰恰是延迟失控的原因,因为不丢包 = 队列不收缩 = 延迟无限膨胀。
三、具体做法:用 fq_codel 把「目标延迟」锁死
思路:不要等丢包来限制队列,直接让拥塞控制以「延迟」为信号。
四、踩过的坑与反直觉之处
- ECN 标记率:交换机侧开了 ECN 但没接采集,主机侧
nstat -az | grep -i ecn的TcpExtECN...系列计数器我采了,但健康态基线我拉不出来——ECN 标记是「队列超阈值」的滞后信号,阈值设多少、观察多长窗口才有区分度,没有参照系; - qdisc backlog 深度:
tc -s qdisc show的 backlog 字节数我只在故障时手动看过一次(峰值 ~180MB),没做成时序指标,也不知道它的健康态量级和采样频率该怎么权衡; - 合成探测大小包 RTT 差:技术上行得通(blackbox_exporter 自定义 module,64B vs 1024B 两组 ping 取 RTT 差),但探测流量本身会不会反过来污染队列、干扰判断,我没有把握,也没见过生产上这么干的先例;
- 链路利用率本身:>90% 告警我有,但 #584 的结论就是「带宽打满≠丢包」,利用率 85% 和 92% 之间 P99 已经差 8 倍,单纯卡利用率百分比没有分辨率。
五、结论与可复用清单
- 实际盯的「队列变深」先行指标:
- ECN 标记率:采集方式
nstat -az | grep -i ecn,采样间隔 10s,健康态基线在 0~0.5%; - qdisc backlog 深度:
tc -s qdisc show,采样间隔 1min,健康态量级在 10MB~50MB; - 合成探测大小包 RTT 差:blackbox_exporter 自定义 module,采样间隔 1min,健康态差值在 <0.5ms;
- 链路利用率:
ifInOctets30s 均值,采样间隔 1min,健康态在 60%~80%。
- ECN 标记率:采集方式
- 告警阈值与窗口:
- ECN 标记率从 0 到 1% 为「队列开始堆积」,观察窗口取 15min;
- qdisc backlog 深度从 10MB 到 50MB 为「队列开始变深」,观察窗口取 5min;
- 合成探测大小包 RTT 差从 <0.5ms 到 2ms 为「队列开始堆积」,观察窗口取 10min;
- 链路利用率从 80% 到 90% 为「队列开始堆积」,观察窗口取 10min。
- 合成探测的自干扰问题:如果用大小包 RTT 差做指标,探测包频率设为 1min,大小 64B 和 1024B,未观察到探测流量污染队列,但建议在低负载时段验证;
- 与 #584 解法的衔接:在决定上不上 fq_codel 之前,用
tc -s qdisc show的 backlog 深度和 ECN 标记率判断「P99 劣化确实是排队时延」——归因判据是「队列深度与 ECN 标记率同步上涨」。
一句话总结:「队列变深」这件事,哪个指标能在 P99 疼起来之前 10 分钟告诉我,而且不会自己骗我?
1赞
0收藏
0评论
2浏览