netdev_max_backlog 控制的是内核软中断(NET_RX)从网卡DMA区批量取包前的中间积压队列,即per-CPU backlog queue,非硬件队列也非socket缓冲区;默认1000在千兆以上、RTT>1ms场景易溢出,导致packet receive errors上升。

netdev_max_backlog 控制的是什么队列
它不是网卡硬件队列,也不是 socket 发送/接收缓冲区,而是内核软中断(NET_RX)从网卡 DMA 区域批量取包时的中间积压队列。当协议栈处理不过来,包就会堆在这里。默认值 1000 在千兆以上链路、RTT > 1ms 的场景下极易溢出,直接导致 netstat -s | grep "dropped" 中的 packet receive errors 上升。
估算公式:建议值 ≈ 带宽(Mbps)× RTT(ms)÷ 8 × 2~3,单位是“包数”。例如千兆链路(1000 Mbps)、RTT 2ms,粗算得 500~750 包,实际常设为 5000 更稳妥。
- 临时生效:
sudo sysctl -w net.core.netdev_max_backlog=5000 - 永久生效:在
/etc/sysctl.conf中添加net.core.netdev_max_backlog = 5000,再运行sudo sysctl -p - 该参数只影响接收路径的“软中断前排队”,不替代 RPS 或 ring buffer 配置
ethtool -G 设置的是网卡 ring buffer 大小
这是真正由网卡驱动管理的硬件级环形缓冲区(RX/TX ring),位于网卡 DMA 内存中。它比 netdev_max_backlog 更靠近硬件,调大能缓解驱动来不及提交/回收描述符的问题。
先查支持上限:ethtool -g eth0,看 Pre-set maximums 行;再设当前值:sudo ethtool -G eth0 rx 4096 tx 4096。注意:
- igb 驱动最大只支持
4096,i40e 可达32768,超出会报Operation not supported - 执行时接口会短暂 down/up,生产环境建议安排维护窗口
- 该设置重启后保留,但若驱动被卸载重载(如
modprobe -r igb && modprobe igb),需重新执行
txqueuelen 是设备层发送队列长度
它是内核向网卡提交待发包的队列深度,单位是“包”,由 ip link 管理,和 ring buffer、netdev_max_backlog 完全不同层级。
常见误区是盲目拉高:txqueuelen 设太大可能增加延迟、触发驱动 busy 错误(dmesg | grep tx 可见),甚至引发 TCP 重传异常。
- 千兆网卡常用
1000~5000,万兆可试5000,但必须实测验证 - 临时设置:
sudo ip link set dev eth0 txqueuelen 5000 - 持久化不能靠
nmcli直接写,得用 NetworkManager dispatcher 脚本或 systemd service 自动触发 - DPDK/XDP 场景下该参数完全无效,发送队列由应用层控制
别漏掉 RPS 和多队列协同
单靠调大队列长度没用——如果所有网络中断都打到一个 CPU 核上,软中断处理不过来,队列照样溢出。必须配合 RSS/RPS 分流:
- 查当前队列数:
ethtool -l eth0,确认是否启用多队列(Combined数值) - 设为与 CPU 核心数一致(如 8 核就设
sudo ethtool -L eth0 combined 8) - 开启 RPS:
echo f > /sys/class/net/eth0/queues/rx-0/rps_cpus(十六进制掩码,f=4核) - 检查中断分布:
cat /proc/interrupts | grep eth0,确保各 CPU 的rx中断计数接近
真正卡住吞吐的,往往不是队列长度本身,而是中断不均 + 处理逻辑串行化。调参前务必先看 /proc/interrupts 和 top -H 中软中断线程(ksoftirqd/N)的 CPU 占用。


















