首页/系统/Linux 内核与性能调优速查/net.ipv4.tcp_dsack 重复 SACK
网络栈调优98 条

net.ipv4.tcp_dsack 重复 SACK

D-SACK 让接收方报告重复收到的数据段,发送方可据此识别伪重传与网络重复包,修正拥塞窗口判断。

什么是 D-SACK

D-SACK(Duplicate SACK,RFC 2883)让接收方在 SACK 选项里明确指出“这段数据我重复收到了”。发送方据此可以区分两类完全不同的情况:真正的丢包需要重传与降窗,而伪重传(原包只是延迟到达,接收方重复确认触发了重传)或路径上的重复报文则不应被当成拥塞信号。Linux 的 net.ipv4.tcp_dsack 默认开启,它与 tcp_sack 一起工作。

基本信息

参数路径net.ipv4.tcp_dsack
默认值1(开启)
依赖tcp_sack 需要开启,SACK 选项里才能携带重复段信息
规范RFC 2883,IPv4 与 IPv6 共用一份实现
生效范围内核全局,修改后对新连接生效
观测nstat/nstat -az 的 TcpExt 计数、抓包看 SACK 选项

典型使用场景

  • 排查“莫名重传”:区分伪重传与真丢包,避免误判链路质量
  • 重复报文诊断:确认中间设备或隧道封装是否造成重复
  • 拥塞控制评估:重复 SACK 反馈帮助内核修正 cwnd 回退幅度
  • 弱网与长肥管道优化:减少不必要的降速,保持吞吐
  • 与 tcp_sack 组合核对:确认两端与中间设备没有剥离 SACK 选项

查看与观察

查看与观察
sysctl net.ipv4.tcp_dsack                     # 当前取值
sysctl net.ipv4.tcp_sack                      # 依赖项是否开启
nstat -az 2>/dev/null | grep -i sack | head    # 重传与 SACK 相关计数
ss -tin dst :443 | grep -m2 -o 'retrans:[0-9/]*'   # 单连接重传次数
tcpdump -i eth0 -n 'tcp[tcpflags] & tcp-ack != 0' -c 20 -v   # 看 SACK 选项是否出现
# 如需关闭(不推荐):sysctl -w net.ipv4.tcp_dsack=0

计数与现象对照

现象含义处置
重传计数上升但无丢包证据可能是伪重传确认 D-SACK 与 SACK 是否生效
抓包看到重复序列号路径重复报文查中间设备与隧道配置
SACK 选项完全不出现中间设备剥离或被关闭核对两端 sysctl 与设备策略
重传比例高且伴随超时真实丢包按拥塞与链路方向排查
这些参数属于“默认正确”的一类:除非有明确证据指向 SACK 相关异常,不建议为省事直接关掉,关闭后会削弱拥塞控制对丢包的判断能力。
nstat 的 TcpExt 计数是系统级累计值,判断趋势要看增量:先记录一个时间点,等几分钟再做差,才有可比性。
部分防火墙或负载均衡设备会重写或剥离 TCP 选项,导致 SACK/D-SACK 在链路上失效;出现“本机开着但看不到”时优先怀疑中间设备。

易错点

  • 通常无需调整,它必须与 tcp_sack 联动生效,只开一个或只关一个都会产生意料之外的行为
  • 排查重复包问题时结合抓包看序列号是否真的重复,只看计数器容易把正常重传误判为异常
  • 把 SACK 相关开关当成提高吞吐的万能钥匙,实际收益取决于对端与中间路径的支持情况
  • 在中间设备做 TCP 选项改写却不自知,导致两端参数都正常但行为与预期不符

数据来源与参考

  • Linux 内核 Documentation/networking/
  • RFC 2883(D-SACK)
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌