1
2
3
4
5
6
7
作者:李晓辉

联系方式:

1. 微信:Lxh_Chat

2. 邮箱:939958092@qq.com

上一篇我们聊了怎么用 BDP 调整网络缓冲区,解决高速网络下数据“跑不满”的问题。

今天再聊一个更「物理」的优化:把 MTU 从 1500 提升到 9000,也就是巨帧(Jumbo Frames)。

我今天这篇文章目标很直接,在网络条件允许的情况下,让同一个高性能以太网网络中的设备统一使用巨帧,减少协议头部开销和数据包处理次数,从而争取更高的吞吐量和更低的 CPU 开销。

一、为什么要搞巨帧?先算笔开销账

网络传输数据,可以简单理解为:协议头部 + 实际载荷。

以太网帧本身有头部和帧校验序列(FCS),再加上 IP、TCP 或 UDP 的协议头,真正用于承载应用数据的部分并不是全部。

这里先用一个简化模型算笔账。假设每个数据包的总协议开销为 52 字节:

  • 标准 MTU 1500:(52 / 1500 \approx 3.47%)
  • 巨帧 MTU 9000:(52 / 9000 \approx 0.58%)

注意,这里是简化后的比例计算,实际以太网的线路开销还涉及帧头、FCS、前导码和帧间隙等因素。

从这个模型可以看出,单个数据包承载的数据越多,固定协议开销占比通常就越低。

再想一个问题:如果应用要传输 900 KB 的数据,暂时不考虑其他协议开销,使用 1500 字节 MTU,大约需要 600 个数据包;如果使用 9000 字节 MTU,则大约只需要 100 个数据包。

数据包数量减少,意味着网卡、驱动程序和内核需要处理的报文数量也可能减少。

这就像搬家:原来每次只能搬 15 件货物,现在一次可以搬 90 件。搬运次数少了,自然有机会降低整体开销。

不过要注意,巨帧并不意味着中断次数一定按相同比例下降。实际效果还取决于网卡的中断合并、接收队列、NAPI 轮询以及硬件卸载能力。

巨帧不是想开就开,有几个硬条件

先说结论:必须确保端到端路径能够承载对应大小的数据包。

硬件和网络设备必须支持

巨帧并没有一个所有以太网设备都必须统一采用的 9000 字节标准上限。不同网卡、交换机和操作系统对巨帧的支持能力可能不同,厂商所说的最大帧长也不一定等于 MTU。

企业环境中常见的是 MTU 9000,但部署前一定要核对设备规格。

端到端 MTU 必须匹配

假设服务器 A 的 MTU 是 9000,交换机和服务器 B 也支持对应的帧长,那么巨帧才能正常通过。

如果中间某台交换机只允许较小的帧长,就可能出现丢包。需要注意,部分设备可以配置更大的帧长,但必须确认其配置口径是否包含以太网头部和 FCS。

因此,修改 MTU 时不能只改服务器,还要检查交换机、VLAN、路由接口以及通信对端。

什么场景更适合使用巨帧?

巨帧比较适合网络路径可控、数据量大、传输持续时间长的场景,例如:

  • iSCSI 存储网络和部分 NVMe-oF 部署
  • 虚拟化集群之间的大量数据传输
  • 备份、数据复制和大文件传输
  • 高性能计算集群

尤其是存储网络,减少每单位数据对应的协议处理开销,可能带来实际收益。

但这并不意味着所有 SAN 或 NVMe-oF 网络都必须使用巨帧。是否启用,仍要结合厂商建议、实际工作负载和性能测试决定。

MTU 不匹配为什么会导致连接黑洞?

MTU 不匹配最麻烦的地方,是它不一定表现为“网络完全不通”。

例如,TCP 三次握手通常使用较小的数据包,即使网络路径的 MTU 存在问题,连接也可能成功建立。等到真正传输大数据时,数据包才开始被丢弃。

这时你可能会发现:

  • SSH 能连接,但执行命令或传输文件时卡住
  • TCP 连接已经建立,业务请求却迟迟没有响应
  • 小包 ping 正常,大包 ping 却失败

这类问题可能就是路径 MTU 发现(PMTUD)失败导致的黑洞。

对于 IPv4,如果数据包设置了 DF(Don’t Fragment,不分段)标志,路由器不能对其进行 IPv4 分片;如果数据包超过出口 MTU,路由器通常需要返回 ICMP Destination Unreachable、Fragmentation Needed 消息。

IPv6 路由器不会替发送端分片,超出链路 MTU 时会返回 ICMPv6 Packet Too Big 消息,由发送端调整数据包大小。

如果防火墙错误地过滤了这些必要的 ICMP 报文,发送端可能无法正确发现路径 MTU,最终出现业务卡顿甚至连接黑洞。

Linux 可以通过下面的参数启用 TCP MTU 探测:

1
2
[root@host1 ~]# sysctl net.ipv4.tcp_mtu_probing
net.ipv4.tcp_mtu_probing = 0

常见取值如下:

  • 0:禁用 TCP MTU 探测
  • 1:检测到疑似 PMTU 黑洞时启用探测
  • 2:始终启用探测

但它并不是解决所有 MTU 问题的万能开关。正确配置网络设备、允许必要的 ICMP 报文通过,仍然是优先事项。

在 RHEL 10 上怎么配置巨帧?

推荐使用 nmcli 修改 NetworkManager 连接配置,而不是直接修改配置文件。

先确认网卡对应的连接名称:

1
2
3
4
[root@host1 ~]# nmcli connection show
NAME UUID TYPE DEVICE
ens160 08864eb2-7927-3a89-b954-4dbabc5db128 ethernet ens160
lo 483ae556-41bc-42a8-baa0-df0031b3ab88 loopback lo

假设连接名称是 ens160,可以这样配置:

1
2
[root@host1 ~]# nmcli connection modify ens160 802-3-ethernet.mtu 9000
[root@host1 ~]# nmcli connection down ens160 && nmcli connection up ens160

验证生效情况

1
2
3
4
5
[root@host1 ~]# ip link show ens160
2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 9000 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 00:0c:29:29:c1:31 brd ff:ff:ff:ff:ff:ff
altname enp3s0
altname enx000c2929c131

输出中包含 mtu 9000,说明接口当前配置的 MTU 已经变成 9000。

注意:重新激活网络连接可能造成 SSH 会话中断。远程生产服务器建议通过控制台操作,或者提前准备回滚方案。

VLAN 环境要注意什么?

如果流量经过 VLAN 接口,就需要同时检查 VLAN 接口和物理父接口的配置,以及交换机端口允许的最大帧长。

例如,VLAN 接口设置了 MTU 9000,并不意味着底层物理链路一定能承载对应的帧长。部分设备允许父接口保持较大的帧长余量,但具体要求取决于设备实现和封装开销,不能简单认为所有父接口都必须严格设置为 9000。

怎么验证巨帧真的打通了?

配置完成后,不要只看 ip link show。它只能证明本机接口配置了多大的 MTU,并不能证明端到端链路没有问题。

Linux 下可以使用 ping 测试:

1
2
3
4
5
6
7
8
9
10
11
[root@host1 ~]# ping -c 4 -s 8972 -M do 192.168.8.129
PING 192.168.8.129 (192.168.8.129) 8972(9000) bytes of data.
8980 bytes from 192.168.8.129: icmp_seq=1 ttl=64 time=0.519 ms
8980 bytes from 192.168.8.129: icmp_seq=2 ttl=64 time=0.602 ms
8980 bytes from 192.168.8.129: icmp_seq=3 ttl=64 time=0.484 ms
8980 bytes from 192.168.8.129: icmp_seq=4 ttl=64 time=0.480 ms

--- 192.168.8.129 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3054ms
rtt min/avg/max/mdev = 0.480/0.521/0.602/0.049 ms

为什么是 8972?

对于常见的 IPv4 环境:

  • ICMP 数据:8972 字节
  • IPv4 头部:20 字节
  • ICMP 头部:8 字节

合计正好是:

(8972 + 20 + 8 = 9000)

这里的 9000 指的是 IP 层数据包长度,对应 MTU 9000。-M do 表示不允许 IPv4 分片。

如果测试成功,说明这个大小的 IPv4 数据包可以到达目标并获得响应;如果失败,则需要结合错误信息排查目标端配置、路径 MTU、防火墙策略和交换机帧长限制。

需要注意,这个测试针对常见的 IPv4、无额外 IP 头部选项的情况。IPv6 的头部长度不同,测试参数也需要相应调整。

用 iperf3 对比巨帧前后的性能

网络调优不能只凭感觉,应该先建立基线,再进行对比。

第一步:记录原始配置

确认客户端和服务器的 MTU 都是 1500,并记录测试前的网络状态:

1
ip link show

第二步:启动服务端

在服务器上执行:

1
iperf3 -s

第三步:客户端进行测试

在客户端执行:

1
iperf3 -c host1 -t 10

建议每种配置至少测试几次,记录吞吐量、CPU 使用情况和测试环境。

第四步:启用巨帧后重新测试

确认通信路径中的设备都支持巨帧,再将相应接口配置为 MTU 9000,重复相同的测试。

重点对比:

  • 吞吐量: 是否有所提升
  • CPU 使用率: 完成相同数据传输所需的 CPU 资源是否减少
  • 重传和丢包: 是否出现异常
  • 业务延迟: 是否符合实际需求

这里有一个容易误解的地方:MTU 1500 并不意味着 iperf3 的吞吐量只能达到几百 Kbit/s,也不意味着 CPU 一定很高。

在正常的千兆或万兆网络中,标准 MTU 同样可以实现很高的吞吐量。最终效果取决于网卡性能、链路速率、CPU、TCP 参数、卸载能力以及测试负载。

如果测试前后吞吐量没有明显变化,也不代表巨帧配置失败。可能是当前网络的瓶颈根本不在报文处理开销上。

巨帧之外,还有哪些优化手段?

巨帧不是降低网络 CPU 开销的唯一办法。现代网卡通常还支持多种硬件卸载和收包优化技术。

技术主要作用
TSO将较大的 TCP 数据交给网卡分段,减少 CPU 逐段处理的工作
GRO在接收路径合并符合条件的数据包,降低协议栈处理开销
中断合并减少网卡频繁触发中断的开销
NAPI在高负载下通过轮询批量处理接收数据包

其中,TSO 主要作用于发送路径,GRO 主要作用于接收路径;LRO 也是接收端合并技术,但在转发等场景下有额外限制,不能与 GRO 完全等同。

这些机制可以与 MTU 优化配合使用,但它们解决的问题并不完全相同。

最后总结一下: 巨帧的核心价值,是让每个数据包承载更多有效数据,降低单位数据对应的报文处理开销。对于大流量、长时间传输、网络路径可控的业务,值得进行测试;对于普通办公网络、跨公网通信或配置难以统一的复杂网络,则不一定值得启用。

真正的网络调优,不是参数越大越好,而是找到瓶颈、建立基线,再用数据验证优化是否有效。