物理层优化:网卡选型、光纤与铜缆、PCIe与NUMA绑定

各位同学,咱们今天聊物理层。很多人觉得这层就是插插线、装装卡,没什么技术含量。我刚开始做低延迟网络时也这么想,直到被现实狠狠教育了一回——换了一块网卡,延迟直接砍掉一半。嗯,从那天起,我再也不敢小看物理层了。

网卡选型:Solarflare vs Mellanox

先说网卡。市面上做低延迟网卡的就那么几家,我接触最多的就是Solarflare和Mellanox。这两家风格完全不同,我分别说说我的体会。

Solarflare:为极致延迟而生

Solarflare的网卡,说白了就是为高频交易量身定做的。它的核心优势是硬件时间戳用户态网络栈。我在项目中实测过,Solarflare SFN8522在开启OpenOnload之后,TCP延迟能从常规的10微秒降到2微秒以内。什么概念?就是你的数据包几乎不经过内核,直接在用户态完成收发。

关键特性:

  • OpenOnload:用户态网络加速库,绕过内核协议栈
  • Ethernet PTP硬件时间戳:精度可达纳秒级
  • TCP直接卸载到硬件,CPU几乎不参与

不过Solarflare有个坑——它家的驱动和固件更新比较频繁,我曾经因为固件版本不匹配,导致OpenOnload死活跑不起来。排查了整整两天,最后发现是固件少打了一个补丁。所以我的建议是:拿到卡先刷最新固件,别偷懒

Mellanox:生态更开放

Mellanox(现在叫NVIDIA Networking)走的是另一条路。它家的ConnectX系列网卡,支持RoCEv2和InfiniBand,适合需要RDMA的场景。我个人觉得,如果你的业务需要跨节点传输大量数据,Mellanox是更好的选择。

举个例子,我在一个分布式存储项目中用了ConnectX-6,配合RDMA,节点间的内存拷贝延迟从20微秒降到了3微秒。而且Mellanox的驱动文档写得比较清楚,不像Solarflare那样藏着掖着。

对比项 Solarflare Mellanox
核心优势 用户态网络栈、硬件时间戳 RDMA、RoCEv2、InfiniBand
典型延迟 1-2微秒(TCP) 1-3微秒(RDMA)
适用场景 高频交易、金融 分布式存储、HPC、AI
驱动复杂度 较高,需配合OpenOnload 中等,文档完善

我的建议:如果你做的是高频交易,闭眼选Solarflare。如果是分布式存储或AI训练,Mellanox更省心。当然,预算充足的话,两个都备着也行——我在机房里就混用过,效果不错。

光纤与铜缆:选错线,延迟翻倍

很多人觉得线缆无所谓,能通就行。我告诉你,大错特错。线缆的物理特性直接影响信号质量和延迟。

铜缆:短距离的性价比之王

铜缆(DAC直连铜缆)在10米以内表现很好。它的延迟极低,因为不需要光电转换。我在机柜内部布线时,全部用DAC铜缆,延迟可以控制在0.1微秒以内。而且铜缆便宜,一根25G的DAC线也就几十块钱。

但铜缆有个致命问题——距离。超过10米,信号衰减就很明显了。我曾经在跨机柜的场景下用了15米的铜缆,结果丢包率直接飙到1%。排查了半天,换成光纤就好了。所以记住:10米以内用铜缆,超过10米必须上光纤

光纤:远距离的稳定选择

光纤的优势是距离远、抗干扰强。但光纤也有坑——光模块的兼容性。我遇到过最离谱的事:同一批光模块,插在Solarflare卡上能跑满,插在Mellanox卡上就降速。后来发现是光模块的EEPROM信息没写对,导致网卡识别错误。

避坑指南:买光模块时,一定要确认它和你的网卡兼容。我建议直接买网卡厂商认证过的模块,别为了省几十块钱去淘宝买杂牌。我曾经吃过这个亏,省了50块,多花了三天排查问题。

另外,光纤的弯曲半径要注意。我见过有人把光纤折成90度角,结果光信号直接断了。光纤可以弯,但半径不能小于5厘米,这是底线。

PCIe通道与NUMA绑定:让数据少跑路

网卡选好了,线缆接好了,但数据还是慢?问题很可能出在PCIe和NUMA上。说白了,就是数据从网卡到CPU的路径太长,或者走错了路。

PCIe通道:带宽和延迟的平衡

现在的网卡都是PCIe 3.0或4.0接口。一块100G网卡,需要至少PCIe 3.0 x16的带宽。如果插在x8的槽位上,带宽直接砍半,延迟也会增加。

我个人的习惯是:网卡一定要插在直连CPU的PCIe槽上,不要走PCH(平台控制器)桥接。PCH桥接的延迟比直连高5-10微秒,对于低延迟场景来说,这个差距是致命的。

# 查看PCIe设备所在的NUMA节点
lspci -vvv | grep -E "NUMA|PCI bridge"

# 示例输出
# 0000:03:00.0 Ethernet controller: Solarflare Communications ...
#         NUMA node: 0
# 0000:81:00.0 Ethernet controller: Mellanox Technologies ...
#         NUMA node: 1

你看,上面的输出显示Solarflare卡在NUMA node 0,Mellanox卡在NUMA node 1。如果你的应用程序跑在node 0上,却用了node 1的网卡,数据就要跨NUMA传输,延迟至少增加20%。

NUMA绑定:让网卡和CPU做邻居

NUMA绑定的核心原则就一句话:网卡和它要服务的CPU在同一个NUMA节点上。怎么做到?

  • 首先,用lspcilstopo查看网卡所在的NUMA节点
  • 然后,用numactl把应用程序绑定到同一个节点
  • 最后,用irqbalance或手动设置中断亲和性,让网卡中断也落在同一个节点上
# 绑定应用程序到NUMA node 0
numactl --cpunodebind=0 --membind=0 ./my_low_latency_app

# 设置网卡中断亲和性
echo 1 > /proc/irq/$(cat /sys/class/net/eth0/device/irq)/smp_affinity

这里有个细节:smp_affinity的值是十六进制掩码。比如你想让中断落在CPU 0上,就写1;落在CPU 1上,写2;落在CPU 0和1上,写3。我一般只绑定一个CPU核心,避免中断在不同核心间迁移带来的抖动。

实战经验:我在一个项目中,把网卡从PCH桥接的槽位移到直连CPU的槽位,同时做了NUMA绑定,延迟从15微秒降到了5微秒。就改了个插槽位置和几行配置,效果立竿见影。

知识体系总览

下面这张图,我把物理层优化的核心逻辑画出来了。你一看就明白:网卡、线缆、PCIe/NUMA,这三者环环相扣,任何一个环节出问题,延迟都会崩。

物理层优化核心逻辑 网卡选型 Solarflare Mellanox 用户态 vs RDMA 线缆选择 铜缆(DAC) 光纤 距离 vs 成本 PCIe & NUMA 直连CPU槽位 NUMA绑定 中断亲和性 三者环环相扣 网卡决定上限,线缆决定下限,PCIe/NUMA决定实际表现 任何一个环节出问题,延迟都会崩

一句话总结:物理层优化没有捷径,就是选对卡、插对线、绑对核。这三步走完,你的网络延迟至少能降一半。剩下的,就是应用层的事了。

专注资料整理