net.core.netdev_max_backlog是软中断处理前网卡驱动接收队列最大包数,仅在软中断处理跟不上收包速度时调大才有效;需配合RSS、IRQ均衡、dev_weight等调整,并通过RcvbufErrors和收包差值验证是否真丢包。

net.core.netdev_max_backlog 是什么,改它真能提升吞吐?
net.core.netdev_max_backlog 控制的是内核在软中断(softirq)处理网络包之前,允许网卡驱动暂存到接收队列(per-CPU backlog queue)的最大包数量。它不等于网卡硬件队列(如 rx ring),也不影响 TCP 接收窗口,只管“从硬中断退出后、进协议栈前”这段缓冲。
改大它,**只有在软中断处理跟不上网卡收包速度时才有意义**——典型场景是:高吞吐(比如 >10Gbps)、小包(64B)、CPU 软中断处理瓶颈(si 占用高)、且 netstat -s | grep "packet receive errors" 显示 receiver error 或 drop at input。
常见误判点:
- 看到
netstat -s 里有 listen overflows,其实是 net.core.somaxconn 或应用 accept() 太慢,和 netdev_max_backlog 无关
- TCP 层丢包(如
TCPBacklogDrop)通常来自 sk->sk_receive_queue 满,由 net.core.rmem_max 和应用读取速度决定,不是这个参数
- 调大但没配好 IRQ balance 或 RSS,导致单 CPU 软中断过载,反而更易丢包
怎么查当前值和是否真在丢包?
直接读取:
cat /proc/sys/net/core/netdev_max_backlog
但关键不是看数值,是看有没有实际溢出:
- 运行
watch -n1 'cat /proc/net/snmp | grep -A1 Tcp | tail -1',关注 TcpExt: TCPBacklogDrop 是否持续增长(注意:这是 socket backlog drop,非 netdev)
- 真正对应
netdev_max_backlog 的计数器是:cat /proc/net/snmp | grep -i "Rcv" | awk '{print $3}' —— 这个 RcvbufErrors 在内核 5.10+ 才准确映射为 backlog overflow;老内核得看 /proc/net/netstat 中 UdpInErrors 或 TcpExt: ListenOverflows(不可靠)
- 更准的方式:抓包对比网卡统计与协议栈收包数:
ethtool -S eth0 | grep rx_packets vs netstat -s | grep "segments received",差值突增且伴随 softirq 高,才值得调
修改方法及必须同步调整的参数
临时生效(重启失效):
sysctl -w net.core.netdev_max_backlog=5000
永久生效(写入 /etc/sysctl.conf):
echo "net.core.netdev_max_backlog = 5000" >> /etc/sysctl.conf<br>sysctl -p
但单独改它大概率无效,必须配合:
- 确保 RSS(Receive Side Scaling)开启且队列数 ≥ CPU 核数:
ethtool -L eth0 combined N(N 一般设为逻辑 CPU 数)
- 绑定 IRQ 到不同 CPU:
echo 1 > /proc/irq/*/smp_affinity_list(需按 RSS 队列逐个配,不能全绑一个核)
- 增大
net.core.dev_weight(默认 64),让每次软中断处理更多包:sysctl -w net.core.dev_weight=128(上限一般 ≤ 300,过高会饿死其他 softirq)
- 检查
net.core.rmem_default 和 rmem_max 是否足够,避免包进了协议栈却卡在 socket buffer
设多大才合适?别盲目堆数字
没有通用值。取决于:
- 网卡收包速率(pps):比如 1M pps,处理延迟 100μs/包 → 理论 backlog 需 ≥ 100 包;但要留余量,通常 ×3~5
- CPU 软中断处理能力:用
perf record -e irq:softirq_entry -g -a sleep 5 看 net_rx_action 耗时
- 内存压力:每个包在 backlog 中占约 2KB(含 skb 结构),设 5000 就额外占用 ~10MB per CPU
经验值参考(仅限 10G+ 小包场景):
- 单核软中断瓶颈明显 → 先优化 IRQ 分布,
netdev_max_backlog 建议 1000~2000
- 多核均衡、pps > 500k → 可试 3000~5000,再观察
RcvbufErrors 是否下降
- 超过 6000 很少有收益,反而可能因 cache line false sharing 拖慢 softirq
真正容易被忽略的是:这个参数只在「驱动把包交给协议栈」这一步起作用,而现代网卡大多用 XDP 或 busy-polling 绕过它。如果你启用了 ethtool -C eth0 rx-usecs 50 或 XDP 程序,netdev_max_backlog 几乎不参与路径。
netstat -s 里有 listen overflows,其实是 net.core.somaxconn 或应用 accept() 太慢,和 netdev_max_backlog 无关TCPBacklogDrop)通常来自 sk->sk_receive_queue 满,由 net.core.rmem_max 和应用读取速度决定,不是这个参数cat /proc/sys/net/core/netdev_max_backlog但关键不是看数值,是看有没有实际溢出:
- 运行
watch -n1 'cat /proc/net/snmp | grep -A1 Tcp | tail -1',关注TcpExt: TCPBacklogDrop是否持续增长(注意:这是 socket backlog drop,非 netdev) - 真正对应
netdev_max_backlog的计数器是:cat /proc/net/snmp | grep -i "Rcv" | awk '{print $3}'—— 这个RcvbufErrors在内核 5.10+ 才准确映射为 backlog overflow;老内核得看/proc/net/netstat中UdpInErrors或TcpExt: ListenOverflows(不可靠) - 更准的方式:抓包对比网卡统计与协议栈收包数:
ethtool -S eth0 | grep rx_packetsvsnetstat -s | grep "segments received",差值突增且伴随softirq高,才值得调
修改方法及必须同步调整的参数
临时生效(重启失效):
sysctl -w net.core.netdev_max_backlog=5000
永久生效(写入 /etc/sysctl.conf):
echo "net.core.netdev_max_backlog = 5000" >> /etc/sysctl.conf<br>sysctl -p
但单独改它大概率无效,必须配合:
- 确保 RSS(Receive Side Scaling)开启且队列数 ≥ CPU 核数:
ethtool -L eth0 combined N(N 一般设为逻辑 CPU 数)
- 绑定 IRQ 到不同 CPU:
echo 1 > /proc/irq/*/smp_affinity_list(需按 RSS 队列逐个配,不能全绑一个核)
- 增大
net.core.dev_weight(默认 64),让每次软中断处理更多包:sysctl -w net.core.dev_weight=128(上限一般 ≤ 300,过高会饿死其他 softirq)
- 检查
net.core.rmem_default 和 rmem_max 是否足够,避免包进了协议栈却卡在 socket buffer
设多大才合适?别盲目堆数字
没有通用值。取决于:
- 网卡收包速率(pps):比如 1M pps,处理延迟 100μs/包 → 理论 backlog 需 ≥ 100 包;但要留余量,通常 ×3~5
- CPU 软中断处理能力:用
perf record -e irq:softirq_entry -g -a sleep 5 看 net_rx_action 耗时
- 内存压力:每个包在 backlog 中占约 2KB(含 skb 结构),设 5000 就额外占用 ~10MB per CPU
经验值参考(仅限 10G+ 小包场景):
- 单核软中断瓶颈明显 → 先优化 IRQ 分布,
netdev_max_backlog 建议 1000~2000
- 多核均衡、pps > 500k → 可试 3000~5000,再观察
RcvbufErrors 是否下降
- 超过 6000 很少有收益,反而可能因 cache line false sharing 拖慢 softirq
真正容易被忽略的是:这个参数只在「驱动把包交给协议栈」这一步起作用,而现代网卡大多用 XDP 或 busy-polling 绕过它。如果你启用了 ethtool -C eth0 rx-usecs 50 或 XDP 程序,netdev_max_backlog 几乎不参与路径。
ethtool -L eth0 combined N(N 一般设为逻辑 CPU 数)echo 1 > /proc/irq/*/smp_affinity_list(需按 RSS 队列逐个配,不能全绑一个核)net.core.dev_weight(默认 64),让每次软中断处理更多包:sysctl -w net.core.dev_weight=128(上限一般 ≤ 300,过高会饿死其他 softirq)net.core.rmem_default 和 rmem_max 是否足够,避免包进了协议栈却卡在 socket buffer- 网卡收包速率(pps):比如 1M pps,处理延迟 100μs/包 → 理论 backlog 需 ≥ 100 包;但要留余量,通常 ×3~5
- CPU 软中断处理能力:用
perf record -e irq:softirq_entry -g -a sleep 5看net_rx_action耗时 - 内存压力:每个包在 backlog 中占约 2KB(含 skb 结构),设 5000 就额外占用 ~10MB per CPU
- 单核软中断瓶颈明显 → 先优化 IRQ 分布,
netdev_max_backlog建议 1000~2000 - 多核均衡、pps > 500k → 可试 3000~5000,再观察
RcvbufErrors是否下降 - 超过 6000 很少有收益,反而可能因 cache line false sharing 拖慢 softirq
ethtool -C eth0 rx-usecs 50 或 XDP 程序,netdev_max_backlog 几乎不参与路径。


















