大带宽服务器的Linux内核优化深度对比评测 - 20260516

前言

大带宽服务器买回来,跑个iperf3发现死活吃不满带宽,CPU还飙到90%?别急着骂机房,八成是内核在“省电模式”拖后腿。本文直接对比默认内核参数针对大带宽场景深度调优的两套方案,用实测数据告诉你差距有多大。所有命令和脚本均可直接复制,跑完看结果。

测试环境

一台轻云互联的大带宽服务器(E5-2680 v4,128G内存,双口25G网卡,系统Ubuntu 22.04 LTS,内核5.15.0),对端用同机房另一台相同配置机器做client,压满双向流量。

# 系统基础参数确认
sysctl net.core.rmem_default net.core.wmem_default
sysctl net.ipv4.tcp_rmem net.ipv4.tcp_wmem
ethtool -g eno1   # 查看当前RX/TX ring buffer大小
cat /proc/interrupts | grep eno1   # 看中断分布

方案A:默认内核参数(裸奔组)

完全不做任何修改,仅安装最新驱动。典型默认值:

net.core.rmem_default = 212992
net.core.wmem_default = 212992
net.ipv4.tcp_rmem = 4096 131072 6291456
net.ipv4.tcp_wmem = 4096 16384 4194304
# 未开启RPS/RFS,IRQ全部落在CPU0

直接用 iperf3 跑单流和8流双向:

# 服务端
iperf3 -s -p 5201 &
iperf3 -s -p 5202 &
...
# 客户端(8条并发)
for i in {1..8}; do iperf3 -c 192.168.1.2 -p $((5200+i)) -t 30 -P 4 & done
wait

结果:单流9.2Gbps,8流总共22Gbps,但CPU0打满100%,网卡丢包率0.3%(通过 ethtool -S eno1 | grep drop 确认)。

方案B:深度调优组(大带宽专用)

针对25Gbps吞吐目标,依次执行以下调整:

1. 内核参数激增

cat > /etc/sysctl.d/99-bigband.conf << 'EOF'
net.core.rmem_default = 134217728
net.core.wmem_default = 134217728
net.core.rmem_max = 268435456
net.core.wmem_max = 268435456
net.ipv4.tcp_rmem = 4096 1048576 134217728
net.ipv4.tcp_wmem = 4096 65536 134217728
net.core.netdev_budget = 600
net.core.netdev_budget_usecs = 4000
net.core.somaxconn = 65535
net.ipv4.tcp_congestion_control = bbr
net.core.default_qdisc = fq
EOF
sysctl -p /etc/sysctl.d/99-bigband.conf

注意: rmem/wmem在4.18+内核中默认受tcp_rmem上限约束,这里直接设到128MB。

2. 网卡Ring Buffer + 中断亲和性

第一步:增大ring buffer(仅限支持的大网卡,如mlx5/ixgbe)

ethtool -G eno1 rx 4096 tx 4096
ethtool -L eno1 combined 8   # 开启8个队列

第二步:手工绑定IRQ到不同物理核心(避开超线程的同时绑定在同一NUMA节点)

# 查看网卡中断号
IRQS=$(grep eno1 /proc/interrupts | awk '{print $1}' | tr -d ':')
i=0
for irq in $IRQS; do
    echo $((i % 8 + 1)) > /proc/irq/$irq/smp_affinity_list
    ((i++))
done

第三步:开启RPS/RFS(避免单队列瓶颈)

# 将CPU1-7的bitmask写入每个队列的rps_cpus
for f in /sys/class/net/eno1/queues/rx-*/rps_cpus; do echo fe > $f; done
# RFS参数
echo 32768 > /proc/sys/net/core/rps_sock_flow_entries
for f in /sys/class/net/eno1/queues/rx-*/rps_flow_cnt; do echo 4096 > $f; done

3. 关闭一切可能的流控和硬件卸载干扰(针对大带宽低延迟)

ethtool -A eno1 rx off tx off  # 关闭pause帧
ethtool -K eno1 gro on gso on tso on   # 保留GRO/GSO(大带宽必须)
ethtool -K eno1 lro off   # 大带宽下LRO会坏包

全部配完后再跑同样的iperf3测试:

# 8流同时 4并行
结果:单流9.8Gbps,8流总共24.2Gbps,CPU总利用率从100%降到42%(平均分布在8个核心),丢包0%,重传率0.01%。

对比总览

项目默认深度调优
单流带宽9.2 Gbps9.8 Gbps
8流总带宽22 Gbps24.2 Gbps
CPU最高核利用率100% (core0)32% (最忙核)
网卡丢包0.3%0%
ping延迟(满载时)0.8ms 抖动0.3ms 稳定

(注:单流性能受限于TCP窗口和网卡单队列能力,调优后提升不大,但多流和CPU负载改善极其明显。)

实战坑点与排错

  • ring buffer设太大导致OOM: 每队列4KB * 4096 = 16MB,8队列128MB,128G内存没问题。但如果你只有16G内存,建议rx 2048 tx 2048。
  • RPS导致跨NUMA访问: 如果你的CPU是多NUMA,必须只用本NUMA的核心来处理对应网卡的中断和RPS,否则延迟暴增。用 numactl --hardware 确定后再写smp_affinity。
  • BBR结合fq的坑: 部分5.x内核(如5.4)下BBR+fq在高带宽下会拥塞窗口过度退缩,导致带宽起伏。可以改用 sysctl net.ipv4.tcp_congestion_control=bbr net.core.default_qdisc=pfifo_fast 解决。
  • 调优后iperf3反而变慢:检查是否开启了 nagleTSO/GSO 被意外关闭。用 ethtool -k eno1 | grep -E 'tcp-seg|generic-seg' 确认。

总结

大带宽服务器的性能瓶颈往往不在硬件,而在内核网络栈的默认保守配置。通过调整缓冲区、绑定IRQ、开启RPS/RFS、精细化ring buffer,可以轻松将多流吞吐从22Gbps拉到24Gbps,同时CPU负载降低60%以上。实测在轻云互联的大带宽服务器上,这套调优方案已稳定运行超过3个月,从未出现丢包或异常抖动。直接套用上面的脚本,你的服务器也能吃满带宽。