Skip to content

高速互联 InfiniBand

InfiniBand 基础

InfiniBand(IB)是专为高性能计算设计的高速网络互联技术,提供极低延迟和极高带宽。

InfiniBand vs 以太网:

指标          InfiniBand HDR    25GbE RoCE    100GbE RoCE
带宽          200Gbps           25Gbps        100Gbps
延迟          ~600ns            ~1-2μs        ~1μs
CPU 开销      极低(RDMA)      低(RDMA)    低(RDMA)
协议          原生 RDMA         RoCE v2       RoCE v2
成本          高                低            中
适用场景      HPC/AI 训练       通用          大规模 AI

InfiniBand 网络架构

胖树(Fat-Tree)拓扑

标准 Fat-Tree 拓扑(k=4,16 节点):

核心层(Core):k/2 × k/2 = 4 台交换机
汇聚层(Aggregation):k = 4 个 Pod,每 Pod k/2 = 2 台
接入层(Edge):k = 4 个 Pod,每 Pod k/2 = 2 台
服务器:k³/4 = 16 台

特点:
  - 任意两台服务器间:最多 2k-1 跳
  - 全双工无阻塞(超额订阅比 1:1)
  - 线性扩展

实际大规模部署(k=40,HDR 200Gbps):
  核心层:400 台 × 40 端口交换机
  汇聚层:800 台 × 40 端口交换机
  接入层:800 台 × 40 端口交换机
  服务器:16,000 台

Dragonfly+ 拓扑(超大规模)

适用:10,000+ 节点的超大规模集群

特点:
  - 比 Fat-Tree 使用更少的交换机
  - 全局路由,任意两节点 2-3 跳
  - 适合 AI 大模型训练集群

InfiniBand 安装配置

驱动安装

bash
# 下载 MLNX_OFED 驱动(Mellanox/NVIDIA InfiniBand 驱动)
# 从 NVIDIA 官网下载对应版本
# https://network.nvidia.com/products/infiniband-drivers/linux/mlnx_ofed/

# 安装
tar xf MLNX_OFED_LINUX-23.10-0.5.5.0-rhel8.8-x86_64.tgz
cd MLNX_OFED_LINUX-23.10-0.5.5.0-rhel8.8-x86_64
./mlnxofedinstall --all --force

# 重启 OpenFabrics 服务
/etc/init.d/openibd restart

# 验证安装
ibstat
# 关注:
#   State: Active
#   Physical state: LinkUp
#   Rate: 200 Gb/sec(HDR)
#   Link layer: InfiniBand

# 查看 IB 设备
ibv_devinfo

子网管理器(Subnet Manager)

bash
# 每个 IB 子网需要一个子网管理器(SM)
# 通常运行在管理节点或 IB 交换机上

# 安装 OpenSM(软件 SM)
yum install -y opensm

# 配置 OpenSM
cat > /etc/opensm/opensm.conf << 'EOF'
# 日志级别
log_flags 0x03

# 优先级(多个 SM 时,优先级高的成为 Master)
sm_priority 15

# 子网前缀
subnet_prefix 0xfe80000000000000
EOF

# 启动 OpenSM
systemctl enable opensm
systemctl start opensm

# 验证 SM 运行
sminfo
# 输出:SM lid 1, SM key 0x0000000000000000, priority 15, state 3 (Master)

网络验证

bash
# 查看 IB 网络拓扑
ibnetdiscover | head -50

# 查看所有 IB 节点
ibnodes

# 测试节点间连通性
ibping -G <目标节点GUID>

# 带宽测试
# 服务端
ib_write_bw -d mlx5_0 -i 1 --report_gbits

# 客户端
ib_write_bw -d mlx5_0 -i 1 --report_gbits <server-hostname>

# 延迟测试
ib_write_lat -d mlx5_0 -i 1 <server-hostname>

# 预期结果(HDR 200Gbps):
# 带宽:~23 GB/s(接近理论值 25 GB/s)
# 延迟:~600ns(P50)

RDMA 编程

基本 RDMA 操作

c
// RDMA Write 示例(简化版)
#include <infiniband/verbs.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define BUFFER_SIZE (1024 * 1024)  // 1MB

int main() {
    struct ibv_device **dev_list;
    struct ibv_device *ib_dev;
    struct ibv_context *ctx;
    struct ibv_pd *pd;
    struct ibv_mr *mr;
    struct ibv_cq *cq;
    struct ibv_qp *qp;
    
    char *buffer = malloc(BUFFER_SIZE);
    memset(buffer, 0, BUFFER_SIZE);
    
    // 1. 获取 IB 设备列表
    dev_list = ibv_get_device_list(NULL);
    ib_dev = dev_list[0];
    
    // 2. 打开设备
    ctx = ibv_open_device(ib_dev);
    
    // 3. 分配保护域
    pd = ibv_alloc_pd(ctx);
    
    // 4. 注册内存区域(允许 RDMA 访问)
    mr = ibv_reg_mr(pd, buffer, BUFFER_SIZE,
                    IBV_ACCESS_LOCAL_WRITE |
                    IBV_ACCESS_REMOTE_WRITE |
                    IBV_ACCESS_REMOTE_READ);
    
    printf("内存注册成功\n");
    printf("  虚拟地址: %p\n", buffer);
    printf("  远程密钥: 0x%x\n", mr->rkey);
    printf("  本地密钥: 0x%x\n", mr->lkey);
    
    // ... 创建 QP,连接到远端,执行 RDMA 操作
    
    // 清理
    ibv_dereg_mr(mr);
    ibv_dealloc_pd(pd);
    ibv_close_device(ctx);
    ibv_free_device_list(dev_list);
    free(buffer);
    
    return 0;
}

IB 网络监控

bash
# 监控 IB 端口统计
perfquery -x  # 查看所有端口错误计数器

# 关键错误计数器:
# SymbolErrors:符号错误(物理层问题)
# LinkRecovers:链路恢复次数
# LinkDowned:链路断开次数
# RcvErrors:接收错误
# XmtDiscards:发送丢弃

# 实时监控带宽
watch -n 1 'perfquery | grep -E "RcvData|XmtData"'

# 使用 ibmon 监控(如果安装)
ibmon -d mlx5_0 -p 1 -i 1

# Prometheus + IB Exporter 监控
# 安装 infiniband-exporter
# 配置 Prometheus 抓取 :9683/metrics

褚成志的云与计算笔记