简介:InfiniBand架构规范第1卷1.7最终版,由IBTA于2023年7月11日发布,是面向数据中心网络工程师、高性能计算架构师和存储系统开发者的权威技术文档。该规范完整定义了IB协议的通用架构,涵盖从1.0到1.7的历次修订细节,并新增了网络探测(Annex A20)、内存放置扩展、大基数交换机管理及XDR速率支持等关键内容,同时整合了虚拟化增强、RoCE-v1和RoCE-v2标准附件,为高性能网络设计、部署与排障提供了明确依据。资源包为单个PDF文件,压缩后大小13.82MB,体积精简,便于本地查阅和关键词检索。目前已有483人浏览学习,适合需要深入理解InfiniBand技术细节的专业读者。通过阅读可快速把握IB规范的最新演进和标准化方向,为数据中心与HPC网络方案选型、实施和优化提供有效支撑。
1. IB Specification Vol 1 Release 1.7 到底是哪份规范:为什么排障前先读它
在 HPC 集群里,判断一块 200G 网卡好不好用,多数人看的是ibstat里的 Active;真正决定它稳不稳的,是一份动辄上千页的协议文档:IB Specification Vol 1-Release-1.7-Final-2023-07-11。这份由 IBTA 在 2023 年 7 月 11 日定稿的卷一规范,是 InfiniBand 网络行为的总依据,链路速率、包格式、传输状态机、子网管理、分区、QoS 和拥塞控制的边界全写在里面。它适合三类人:管集群的网络工程师、写 RDMA 应用的开发、以及要跟设备厂商据理力争的存储工程师。读完它,你能回答一个最实际的问题:错误日志里的一个字段,到底该在主机侧改,在交换机侧改,还是根本不能改。
2. 拆开 Vol 1:从链路速率到传输层的 1.7 关键参数
拿到这份 1.7 最终版,第一反应别是通读。规范的正文像法律条文,每个词都有定义域,线性读三章就会迷失。我的习惯是把它当成一台能回答“谁负责什么”的黑匣子:先搞清楚卷一的管辖边界,再按故障现场反向查。卷一管的是逻辑行为:节点架构、链路状态机、报文头、转发规则、子网管理协议。至于插头长什么样、线缆什么等级,那是 Vol 2 的事,别混着读。
2.1 Vol 1 的章节骨架:从链路状态机到子网管理的边界线在哪
卷一的设计思路是:把可以形式化验证的行为写死,把物理实现的细节留给卷二和厂商。所以你会看到链路状态机被定义成 Down、Init、Armed、Active 四个状态,而不会看到某个品牌光模块的功耗参数。读卷一能解决“协商到 1X 是线的问题还是驱动的问题”这类争议:线的问题会在 Physical 状态上体现,驱动或配置问题则是 Port 状态卡在 Init。这两者的分野,规范里写得很清楚。
我一般会按三步去读,而不是从头翻。先看目录,找到和故障相关的章;再看那一章末尾的字段汇总表,规范习惯把所有字段的定义集中列出来;最后查官方勘误,确认 1.7 是否对某句话做过修订。这三步下来,你对一份上千页文档的实际阅读量通常能压缩到几十页,但这几十页里每句话都能对应到一次排障决策。
| 阅读步骤 | 具体动作 | 目的 |
|---|---|---|
| 第 1 步 | 翻目录与索引,按关键词定位(如 ACK timeout、PKey、SM) | 缩小范围,不从头读 |
| 第 2 步 | 读字段定义表,记录位宽、范围、默认值和 owner | 知道参数归谁管、能改到多少 |
| 第 3 步 | 查勘误与版本说明,对比 1.6 与 1.7 | 防止按旧版本文本做决策 |
为什么字段定义这么关键?因为很多争议的根源是“两边读的不是同一句话”。比如 PKey 的 bit15 是不是 full member 标志,在规范里是一个明确字段,但实现方的文档常常含糊带过。你拿着规范的字段表去和厂商对线,对方才会认真处理;你只说“我感觉不对”,就很容易被当成玄学。
2.2 链路速率、MTU 与 ack_timeout:三个一调就影响全网的关键参数
链路速率是所有人第一时间会查的东西。从 SDR 到 NDR,每 lane 速率翻着倍走:
| 规格 | 每 lane 速率 | 4X 端口标称 |
|---|---|---|
| SDR | 2.5 Gb/s | 10 Gb/s |
| DDR | 5 Gb/s | 20 Gb/s |
| QDR | 10 Gb/s | 40 Gb/s |
| FDR | 14.0625 Gb/s | 56 Gb/s |
| EDR | 25 Gb/s | 100 Gb/s |
| HDR | 50 Gb/s | 200 Gb/s |
| NDR | 100 Gb/s | 400 Gb/s |
速率表只告诉你上限,实际工作速率是协商出来的。规范里把速度和宽度分开表达:速度乘宽度,Active: 4X, HDR才是 200G。最常见的问题是宽度从 4X 掉到 1X,此时带宽直接砍到四分之一,但链路状态依然是 Active,很多人因此漏排。判断依据就是ibv_devinfo -v里的 active_width 字段,而不是看线缆价格。
第二个高频参数是 MTU。InfiniBand 的报文 MTU 只有 256/512/1024/2048/4096 五档,主机和交换机每个端口都得按支持的最大值参与路径计算。子网管理器(SM)做路径计算时,会取整条路径的最小公共 MTU 写进 PathRecord;如果你在 SM 和主机上都设了 4096,但中间某台交换机固件把端口 MTU 降到了 2048,整条链路就会按 2048 走,性能断崖。这个坑在混合厂商组网时特别容易踩。
第三个参数是 ack_timeout,它经常被当成驱动里的一个玄学数字。规范给出的换算公式是 4.096µs × 2^n,n 是寄存器里存的值。短链路 n=10 约 4ms,n=14 约 67ms,n=16 约 268ms。它决定发送端等多久才判定对端没收到,调小了会引发无谓重传,调大了会让故障发现变慢。我的经验是:跨机柜网络起步值设在 14 到 16,别学网上教程为了压延迟调成 10,除非你确定拓扑不超过一跳。
2.3 QoS、分区与拥塞控制:1.7 留给网络工程师的扩展点
1.7 在 QoS 上的框架没有推倒重来:SL(Service Level)还是 0 到 15 共 16 个等级,SL 映射到 Virtual Lane 的条数由硬件决定,报文头里的 SL 字段由发送端填。做多租户或混合负载时,我一般会把存储流量放到单独 SL,给单独 VL,避免和计算流量争 buffer。规范并不规定你应该用 SL 几,只规定映射表怎么组织,具体规划是属于网络工程师的活。
分区机制(PKey)也在卷一里定义。它和以太网 VLAN 最大的区别是:PKey 不只在入方向过滤,还会在出方向参与校验,两个端口必须存在兼容的分区键才能建 QP。这里有个 1.7 里依旧好用的规则:PKey 的 bit15 是 full member 标志,两个 limited member 之间无法互相通信,必须至少一端是 full member。很多人第一次配置时在这里翻车,以为是驱动 bug,其实是规范里早就写明的边界。
拥塞控制是 1.7 里最容易被忽略的部分。规范给了拥塞控制机制的行为框架和报文格式,但把实现丢给芯片。实际测试时,新架构的拥塞控制往往需要交换机和网卡固件同时满足版本矩阵,跨代混跑时我在生产上宁可关闭,人为限定流控,也不愿让黑匣子算法半夜把队列打满。另外说一句 Release-Final 的含义:它不是功能大版本,而是把前面所有勘误合入正文后的稳定版。升级到 1.7 的意义,不在于多了新速率,而在于你拿它去和厂商对线时,文本是唯一的法律。
3. 把规范落到 InfiniBand 实网:参数选型与验证命令
规范只有变成命令能查到的值,才有排障价值。下面这套动作,是我不装网管软件也能在两分钟内确认一台接入节点是否符合 1.7 行为的最小组合。
3.1 用 ibstat 与 ibv_devinfo 核对链路状态机
第一步永远是看链路状态机。ibstat输出里有两段对照信息:Port State 和 Physical Port State。Port State 对应规范里的逻辑状态(Down/Init/Armed/Active),Physical State 对应物理链路可用性。Active 不一定健康,如果 Physical State 不是 LinkUp,说明光模块或线缆侧有问题;如果 Port State 停在 Init,说明 SM 没有完成该端口的配置。
在 shell 里敲ibstat和ibv_devinfo -v,重点看几个字段:Active Width、Active Speed、Active MTU、SM LID。下面是我每次开局都会对着核的表格:
| 检查项 | 期望值 | 异常含义 |
|---|---|---|
| Port State | Active | Init 或 Down 表示 SM 未接管或链路失败 |
| Physical Port State | LinkUp | Polling、Disabled 表示物理层没起来 |
| Active Width | 4X | 1X 表示链路降级,性能只剩四分之一 |
| Active Speed | 与线缆等级一致 | 降档意味着协商没到最高规格 |
| Active MTU | 4096(或按规划) | 2048 会导致吞吐上不去 |
| SM LID | 非 0 | 为 0 说明该端口还没被 SM 分配地址 |
这套命令看到的是结果,要定位是谁造成的,再用ibqueryerrors查端口错误计数器。Symbol Error、Link Recovery 这类计数如果持续增长,多半是物理层问题;RcvError 增长则要看对端和网络。规范定义了这些计数器的语义和清零行为,知道谁定义它,你才知道数字是谁统计的。
3.2 MTU 与 ack_timeout:按规范公式配置而不是拍脑袋
MTU 的配置顺序很重要。我的常规流程是:先把所有计算节点的 MTU 固定为 4096,再在 SM 配置文件里把 max_mtu 设成 4096 并重启,最后用ibv_devinfo -v逐一验证 active_mtu。注意,某些交换机端口即使硬件支持 4096,固件里也默认 2048,SM 会把整条路径按最小值下发。我一般会在开局前写个小脚本,把每个端口的 active_mtu 都抓到日志里,没到 4096 的报警,这个习惯救过我好几次。
ack_timeout 的起点按公式算:先知道你这条链路最差往返时延。托管交换机内部 buffering 也会贡献时延,纯看距离会算小。稳妥做法是拿 perftest 的ib_read_lat测出往返延迟,留 5 到 10 倍余量再套公式。公式是 4.096µs × 2^n,倒推 n 即可;如果你不是靠测试而是靠猜,直接填 14 起步。这个值不是越小越好的性能调优参数,它更像保险丝,宁大勿小。
3.3 用 perftest 交叉验证:规范写的速率不是嘴上说的
在两端分别跑ib_write_bw -d mlx5_0,服务端先起,客户端后起,等它自动协商消息大小。注意这个测试默认只打一个 QP,200G 网卡单 QP 很难跑满,要加-q 8提升 QP 数;要测大包稳态就加-s 1048576、-D 30持续 30 秒。得到的 Bandwidth 是有效 payload 吞吐,协议头开销不会算进去,所以比端口标称低一点是正常的,HDR 跑到 185 到 195 Gb/s 已经说明链路没在丢包。
参数含义是固定的:-d指定设备,-q指定 QP 数,-s指定消息大小,-D指定测试时长。如果不加 QP 数,10G 线都可能只跑出 40G,这种测试结果不能说明链路坏。加-q 8后还不到峰值的八成,重点排查路径 MTU、链路 width 和对端进程 CPU,之后再查 SM 有没有把路径算到低速端口。
4. 子网管理 SM 与分区:1.7 规范里最容易翻车的一层
子网管理器是 InfiniBand 区别于以太网的核心,也是卷一把行为约束得最细致的地方。很多人拿它当路由协议去理解,实际它更像 SDN 控制器:统一分配 LID、计算转发路径、下发转发表。SM 一挂,全网不是立即断,而是新连接无法建立、已有连接开始走错误重传,这种半死不活的状态最考验人。
4.1 LID、SM 与路径计算:为什么全网只有一个真主
规范规定每个端口至少有一个 16 位 LID,SM 负责从地址池分配;GID 则由 GUID 和子网前缀组合成 128 位,对应到报文里的 GRH 头。主机侧ibstat看到的 Port LID 是 SM 分配的,SM LID 是子网管理器所在端口;前者如果是 0,说明该端口还没被 SM 接管。
常见做法是让 opensm 跑在管理节点或一台交换机上,并在配置里指定子网前缀和 GUID 范围。启动后第一件事不是看日志,而是跑ibnetdiscover画出拓扑,再拿它和物理连线比对。规范允许一个子网里跑多个主备 SM,但同一时刻只有一个 master 在发实际转发表;如果你看到日志里反复出现 sweep,就要小心两个 SM 在抢主。
SM 计算路径时会把 MTU、速率、QoS 等级作为约束。换句话说,你在 SM 里没有配好的 MTU,不会因为网卡驱动里写了 4096 而生效。这解释了为什么很多人改了主机参数没用——规范里路径参数的所有者是 SM,不是端节点。
4.2 分区 PKey 的 full/limited 区别与配置
PKey 是 16 位,高 15 位是分区号,bit15 是 full member 标志。0xFFFF 是所有成员都在的管理分区,业务分区用 0x0001 到 0x7FFE 范围。判断两个端口能否通信,不能只看分区号相同,还要看 full/limited 组合:full 与 full、full 与 limited 都通,limited 与 limited 不通。这一条在 1.7 的措辞和 1.6 没有实质差异,但很多人还是在这里翻车。
opensm 的分区配置一般写在发行版对应的 partitions.conf 里,格式是一行一个分区:先是分区名和 PKey,再列 guid。比如给计算分区写compute=0x2, portguid=0x...,把管理端口留在 0xffff 分区。改完重启 opensm 后,要验证的不只是 ping 通,还要在小范围测试两个 limited member 是否真的被挡在外面,因为 PKey 生效的位置在端口认知表里,不在 IP 层。
| 配置项 | 推荐做法 | 原因 |
|---|---|---|
| 业务 PKey | 0x0001 到 0x7FFE | 避免占用管理分区语义 |
| 成员角色 | 节点尽量配 full member | 避免 limited 与 limited 互斥 |
| 管理口 | 留在 0xFFFF | 保证 SM 和故障排查路径永远可通 |
4.3 换线降速、自适应路由与链路重传:规范定义了什么
换线后从 4X 掉到 1X,是链路层最经典的翻车。规范允许端口在协商失败时降级工作,前提是双方都支持低速档位;模块脏、光损大、线缆不支持都会触发。排障时用ibportstate强制固定宽度可以临时确认,但生产环境不要长期强制,因为你把掉线风险从协商失败变成了硬性 error。
1.7 语境下的自适应路由(AR)不是 SM 路径计算的一部分,而是交换芯片在数据面根据拥塞状态选路。规范定义的是 AR 在报头里如何携带 hop 信息,好让接收端还原真实路径;至于算法怎么选,各家不同。所以跨厂商互通时,如果开了 AR,要确认两边对报头字段的解释一致;否则你看到抓包里的路径号与实际走的路径对不上,非常困惑。
链路重传也不是靠可靠传输的泛泛承诺,而是由发送端的重传定时器决定。上一章的 ack_timeout 就是这里的参数。1.7 对拥塞通知的格式做了更明确的定义,但通知之后端到端怎么做,仍然依赖网卡和交换机的实现。我一般把拥塞控制当成必选框架、可选实现:先关掉跑通基础带宽,再开启对比测试,数据不涨就撤回。
5. 避坑实录:围绕 IB Specification Vol 1 的 5 条排障记录
下面这些坑,多数不是硬件坏了,而是行为与规范对不上。每条按现象、原因、解决的顺序写,可以直接拿去对照。我会额外标注规范里对应的定位方向,方便你回卷一查原文。
5.1 链路协商与参数类坑:高频问题怎么定位
**坑 1:新线 Active 1X,带宽只有四分之一。
现象:新到的线缆插上后链路显示 Active,但 perftest 只有四分之一带宽,而且这台设备刚接上去时还是 4X。
原因:规范允许端口在协商失败时降速降宽,链路从 4X fallback 到 1X 后仍能完成 Active。四分之一性能不会让链路 down,所以很容易被漏掉。
解决:先用ibstat看 Active Width,再用ibqueryerrors看 Symbol Error。若该计数持续增长,清洁光模块端面、重插并紧固;同时确认线缆规格是否满足目标速率。若要用固定宽度验证,在维护窗口用ibportstate把端口 width 指定为 4X,如果固定后端口马上 down,基本可以确定是线或模块问题,不要急着找驱动麻烦。
**坑 2:参数看着都对,HDR 网卡带宽停在 100G 附近。
现象:两台 HDR 节点互跑ib_write_bw,加了-q 8仍然只有 100G 上下,网卡和线缆都支持 200G。
原因:PathRecord 中的 MTU 取路径最小值。只要中间某台交换机的端口固件里 MTU=2048,SM 重算后整条路径按 2048 走。主机驱动的 MTU 设置被 PathRecord 覆盖,所以你改主机没用。
解决:登录所有交换机导出每个端口的 active mtu,在 SM 配置里把 mtu 上限写 4096,重启 SM 清空路径缓存。这里有个经验:某些交换机端口类型默认 MTU 不同,比如面向存储的端口可能固件里就是 2048,开局时必须统一拉齐。
**坑 3:重传率高,同一对节点跑多条链路只有一条性能好。
现象:perftest 带宽波动大,ibqueryerrors里重传相关计数增长,但链路状态没有 down。
原因:ack_timeout 设得太小,跨机柜时延超过定时器周期,触发大量不必要的重传。短距离测试时这个值看不出问题,节点一搬到远机柜就原形毕露。
解决:先用ib_read_lat测出实际往返延迟,留 5 到 10 倍余量,再套 4.096µs × 2^n 公式倒推 n。如果嫌麻烦,直接把 ack_timeout 调到 14 到 16 再重测。注意这个参数在驱动和 SM 两侧都有可能出现,优先改发送端。
5.2 分区与软件版本类坑:另外两条血泪经验
**坑 4:分区配置明明一样,RDMA 就是建不了 QP。
现象:两端 PKey 写的是同一个数,IP 能 ping 通,但ib_write_bw建 QP 报错,看起来像权限问题。
原因:IP 走内核协议栈上送处理,而 RDMA 在 QP 建立阶段就要做 PKey 校验。规范里的规则是:两个 limited member 之间无法互通,必须至少一端是 full member。如果你的分区文件里把两边的 PKey 都写成了不带 bit15 的 limited 值,就正好踩中这条。
解决:把双方 PKey 的 bit15 置 1,或修改 partitions.conf 后重启 SM,并在两端用工具确认 pkey table 里出现了预期值。不要靠 ping 成功反推 PKey 正确,那个结论不成立。
**坑 5:换新卡后ibstat找不到设备。
现象:新卡插上后ibstat没有输出,ibv_devinfo -v报 no device found,但系统已经识别到 PCI 设备。
原因:rdma-core 或内核模块版本较旧,不认识新硬件在枚举阶段暴露的设备属性,导致设备没有注册到 verbs 层。这不是硬件坏了,而是软件对 1.7 时代新功能的支持没跟上。
解决:先看 dmesg 里驱动有没有 probe 失败记录,再升级内核和 rdma-core,必要时同步升级固件。如果还不行,对照规范里关于设备索引和虚拟端口定义的章节,确认是枚举问题还是注册失败,再决定找驱动还是找固件。
6. 进阶用法:把规范当断言表,做最小验证再上生产
6.1 一个从规范到命令的核对表
读完卷一,最有价值的产出不是笔记,而是一张你自己的断言表。把关心的字段、命令、期望值列出来,每次开局或排障时跑一遍。以下是我现在固定用的最小表:
| 检查项 | 命令 | 期望值 |
|---|---|---|
| 逻辑状态 | ibstat | Port State: Active |
| 物理状态 | ibstat | Physical State: LinkUp |
| 链路宽度 | ibv_devinfo -v | Active Width: 4X |
| 链路速率 | ibv_devinfo -v | Active Speed: 与线缆一致 |
| 路径 MTU | ibv_devinfo -v | Active MTU: 4096 |
| 错误计数 | ibqueryerrors | 无持续增长的 error 计数 |
这张表里的每一项,在卷一里都能找到对应的字段定义。你不需要记住所有条款,只需要知道去哪儿查、命令怎么读。
6.2 一个两节点最小环境的验证习惯
我吃过一次亏:新集群刚开箱就全量上线,结果节点有一半停在 Init 状态,排查下来只是 SM 的 GUID 列表少了一个机头。从此之后,我坚持先把一台交换机加两台计算节点组成最小子网,把所有断言表跑一遍,再加节点。两节点直连本质上是一个单交换机子网,SM 配一边就够,规范里的 path record、链路状态机在这个环境下全部生效。
在这个最小环境里,还有一个值得做的实验:故意把 ack_timeout 调到最小,看链路会不会出现重传,再调回 14,对比 perftest 输出。这样你能直观感受到定时器对性能的边界。这个实验只有两节点,不会伤到生产,但能让你彻底搞懂为什么不能把 4.096µs × 2^n 当摆设。
这也是我最想强调的:规范不是用来背的,是用来对答案的。把你关心的字段写成断言表,用命令取真值;不会写的就去查卷一的字段定义,直到表和实网完全一致。希望帮到你。
本文还有配套的精品资源,点击获取