大带宽服务器的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 Gbps | 9.8 Gbps |
| 8流总带宽 | 22 Gbps | 24.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反而变慢:检查是否开启了
nagle或TSO/GSO被意外关闭。用ethtool -k eno1 | grep -E 'tcp-seg|generic-seg'确认。
总结
大带宽服务器的性能瓶颈往往不在硬件,而在内核网络栈的默认保守配置。通过调整缓冲区、绑定IRQ、开启RPS/RFS、精细化ring buffer,可以轻松将多流吞吐从22Gbps拉到24Gbps,同时CPU负载降低60%以上。实测在轻云互联的大带宽服务器上,这套调优方案已稳定运行超过3个月,从未出现丢包或异常抖动。直接套用上面的脚本,你的服务器也能吃满带宽。