4、网卡与网络:选型、配置与调优

网卡选型这事儿,我做了十几年高频交易,换过的网卡比换过的键盘还多。说白了,在高频做市这个领域,网卡就是你的“耳朵”和“嘴巴”。耳朵听不清,嘴巴说不快,那策略再牛也白搭。

今天咱们就聊聊两块主流网卡——Solarflare和Mellanox,以及它们背后的核心技术。嗯,这里要注意,不是比谁更好,而是看谁更适合你的场景。

4.1 Solarflare vs Mellanox:两大阵营的较量

我个人习惯把Solarflare叫做“交易所标配”,而Mellanox则是“数据中心之王”。为什么这么说?

对比维度 Solarflare (X2xxx系列) Mellanox (ConnectX系列)
延迟表现 极致低延迟,硬件级时间戳 同样优秀,但略高1-2微秒
生态支持 OpenOnload、EFVI、TCPDirect RDMA、GPUDirect、VMA
硬件时间戳 原生支持,精度<10ns 支持,但需配置PTP
价格 贵,但物有所值 相对便宜,性价比高
典型场景 交易所直连、做市商 数据中心内部、量化基金

我在项目中遇到过这样一个案例:某家做市商原本用Mellanox跑得好好的,但换到Solarflare后,订单处理延迟直接降了30%。为什么?因为Solarflare的硬件时间戳和内核旁路做得更极致。不过话说回来,如果你主要做跨数据中心通信,Mellanox的RDMA能力又是Solarflare比不了的。

核心结论:做市商首选Solarflare,量化基金选Mellanox。如果你预算充足,两个都备着——反正不亏。

4.2 DPDK与内核旁路技术:绕过操作系统

你想想看,传统网络包处理要走内核协议栈,那延迟能低吗?每次数据包进来,CPU要中断、要拷贝、要上下文切换……这一套下来,几十微秒就没了。在高频交易里,这简直是灾难。

DPDK(Data Plane Development Kit)就是干这个的——它让应用程序直接接管网卡,绕过内核。说白了,就是“我的数据我做主”。

# 一个简单的DPDK初始化流程
rte_eal_init(argc, argv);      // 初始化环境抽象层
rte_pktmbuf_pool_create(...);   // 创建内存池
rte_eth_dev_configure(...);     // 配置网卡
rte_eth_rx_queue_setup(...);    // 设置接收队列
rte_eth_tx_queue_setup(...);    // 设置发送队列
rte_eth_dev_start(port_id);     // 启动网卡

// 轮询模式接收数据包
while (1) {
    nb_rx = rte_eth_rx_burst(port_id, 0, pkts_burst, MAX_PKT_BURST);
    // 直接处理,无需中断
}

我曾经踩过一个坑:刚开始用DPDK时,没注意内存池大小,结果在高并发场景下内存耗尽,直接丢包。嗯,从那以后我养成了一个习惯——内存池至少预留30%的余量。

避坑指南:DPDK虽然快,但CPU占用率会飙升到100%。你需要为DPDK预留独立的CPU核心,别让它和策略线程抢资源。

4.3 硬件时间戳与PTP同步

做高频交易,时间就是金钱。但你知道么?软件时间戳的误差可能高达几十微秒。而硬件时间戳,精度能到纳秒级。

PTP(Precision Time Protocol)就是用来同步多台机器时间的。配合硬件时间戳,你可以把整个交易系统的时钟误差控制在100纳秒以内。

# 配置PTP客户端(Linux)
ptp4l -i eth0 -m -S -2          # 启动PTP协议
phc2sys -s eth0 -c CLOCK_REALTIME -m  # 同步系统时钟

# 验证时间戳精度
ethtool -T eth0 | grep "hardware"
# 输出示例:
#   hardware-transmit:  yes
#   hardware-receive:   yes
#   hardware-raw-clock: yes

我记得有一次,交易所要求所有订单必须带硬件时间戳。我们当时用的网卡不支持,结果被罚了不少钱。从那以后,我选网卡的第一条标准就是:必须支持硬件时间戳。

注意:PTP同步需要网络交换机也支持。别买了高端网卡,结果交换机不支持PTP,那就尴尬了。

4.4 网卡中断亲和性设置

最后聊聊中断亲和性。这玩意儿看着不起眼,但调好了能省不少CPU资源。

默认情况下,网卡中断会随机分配到各个CPU核心。这会导致缓存失效、上下文切换频繁。正确的做法是:把中断绑定到指定的CPU核心上。

# 查看当前中断分配
cat /proc/interrupts | grep eth0

# 设置中断亲和性(绑定到CPU 0和1)
echo "3" > /proc/irq/<irq_number>/smp_affinity

# 或者使用irqbalance工具
systemctl stop irqbalance   # 关闭自动平衡
# 手动绑定
echo "1" > /proc/irq/<irq_number>/smp_affinity  # 绑定到CPU 0

我个人习惯的做法是:把网卡中断绑定到CPU 0和1,DPDK轮询线程绑定到CPU 2和3,策略线程绑定到CPU 4-7。这样各司其职,互不干扰。

经验之谈:中断亲和性设置后,记得用perf top观察CPU使用情况。如果某个核心的软中断(softirq)占比过高,说明绑定没做好。

知识体系总览

下面这张图,是我自己总结的网卡与网络调优的核心逻辑。你一看就明白了。

网卡与网络调优核心逻辑 网卡选型 Solarflare vs Mellanox 核心技术 DPDK / 内核旁路 时间同步 硬件时间戳 + PTP 中断优化 中断亲和性设置 最终目标:纳秒级延迟 + 微秒级抖动 注:四个模块缺一不可,任何一个短板都会成为系统瓶颈

好了,网卡和网络这块就聊到这儿。记住一句话:选对网卡是基础,用好DPDK是核心,时间同步是保障,中断优化是细节。四者缺一不可。