物理层优化:网卡选型、光纤与铜缆、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节点上。怎么做到?
- 首先,用
lspci或lstopo查看网卡所在的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,这三者环环相扣,任何一个环节出问题,延迟都会崩。
一句话总结:物理层优化没有捷径,就是选对卡、插对线、绑对核。这三步走完,你的网络延迟至少能降一半。剩下的,就是应用层的事了。