tcpdump 抓到大量 SACK / DSACK 但业务正常的重传优化参数

11次阅读

SACK/DSACK 频繁出现不表示网络故障,而是TCP纠错机制正常工作;需关注重传模式、DSACK重复性及RTO超时占比,结合tcpdump、ss和内核参数(如tcp_sack、tcp_reordering)综合判断与优化。

tcpdump 抓到大量 SACK / DSACK 但业务正常的重传优化参数

为什么看到大量 SACK/DSACK 不代表网络有问题

tcpdump 里频繁出现 SACKDSACK 是 TCP 正常纠错机制在工作,尤其在高丢包率、乱序严重或接收窗口受限的链路上。业务没异常,说明重传及时、恢复快,SACK 已经在起作用——它本身不是问题,而是“问题被妥善处理了”的证据。真正要关注的是重传是否集中在某类包(如首包、尾包)、DSACK 是否反复指向同一段数据(暗示发送端重复发包),或重传间隔是否接近 RTO(说明超时重传开始主导,SACK 失效)。

哪些内核参数影响 SACK 行为和重传效率

linux 默认开启 SACK,但以下参数决定它能否高效工作:

  • net.ipv4.tcp_sack = 1:必须开启,禁用后退到慢速的累计 ACK 重传
  • net.ipv4.tcp_dsack = 1:建议开启,帮助识别重复发送或接收端 DUP,避免误判丢包
  • net.ipv4.tcp_reordering:默认 3,表示允许接收端最大乱序程度;若实际乱序超过该值,会触发过早重传(Fast Retransmit 误触发);可观察 TCP reno fastretransTCP sack reneging 计数器升高来判断是否需调大(如设为 5–8)
  • net.ipv4.tcp_slow_start_after_idle = 0:防止连接空闲后重置 cwnd,避免突发流量下因慢启动导致连续丢包和 SACK 激增

如何确认是 SACK 有效重传还是 RTO 超时重传

仅靠 tcpdump 看 [SACK] 标记不够,得结合时间戳和重传模式判断:

  • tcpdump -nni eth0 'tcp[tcpflags] & (tcp-syn|tcp-fin|tcp-rst) != 0 or tcp[12] & 0xf0 > 0x40' 过滤出带选项的包,重点看 SACK 和重传包的序列号是否匹配已知丢失段
  • 检查重传包是否紧随三个重复 ACK 出现(即 Fast Retransmit),这是 SACK 主导的标志;若重传发生在首个 ACK 后 >RTO 时间,则是超时重传,SACK 已失效
  • ss -i 查看单个连接的 retransretransmitssacked 字段,对比 sacked 占比;若 sacked > retransmits * 0.8,说明 SACK 处理了绝大多数丢包

业务正常时还值得调优吗?重点关注哪几处

值得,尤其当 RTT 波动大、跨运营商或使用弱无线链路时。优化收益不在“修复故障”,而在降低重传延迟、提升吞吐稳定性:

  • 不要盲目调大 tcp_reordering,超过实际乱序程度会掩盖真实丢包,导致 RTO 延长;先用 tcptrace -rwireshark 的 TCP stream Graph 观察乱序分布
  • 若 DSACK 高频出现且 tcp_dsack_ignore 未启用,考虑加 net.ipv4.tcp_dsack_ignore = 1(5.10+ 内核),忽略由接收端 DUP 引起的 DSACK,减少干扰
  • 确保 net.ipv4.tcp_timestamps = 1 开启,否则 PAWS 机制失效,可能引发旧包被误认为新包,间接导致 SACK 信息错乱

最易被忽略的是应用层行为:比如小包突发、无节制的 write() 调用压垮接收端缓冲区,造成伪乱序,此时调参不如控制发包节奏或增大 rmem_max

text=ZqhQzanResources