3、路由基础与LID:LID(本地标识符)的概念、LID分配机制、单一路径转发原理、线性转发表(LFT)结构

各位好,欢迎来到第三讲。今天咱们聊聊InfiniBand网络里最基础、也最容易被忽视的东西——LID。说白了,LID就是每个IB设备在网络里的门牌号。没有它,数据包就找不到北。

我记得刚接触IB网络那会儿,总觉得LID这玩意儿跟IP地址差不多。后来踩了坑才发现,两者完全是两码事。IP地址是分层的,LID是扁平化的。嗯,这个区别很重要,咱们后面细说。

3.1 LID的概念:门牌号还是身份证?

LID的全称是Local Identifier,本地标识符。每个IB端口(注意是端口,不是设备)在子网里都有一个唯一的16位LID值。取值范围从0x0001到0xBFFF,一共49151个可用LID。

你可能会问:为什么不是从0x0000开始?0x0000是保留的,表示无效LID。0xC000到0xFFFE是组播用的,单播用不到。0xFFFF是广播LID。

我在项目里见过有人把LID配成0x0000,结果交换机死活不认。嗯,这种低级错误其实挺常见的,尤其是新手。

关键点:LID是端口级别的标识,不是设备级别的。一个双端口HCA卡有两个LID,一个交换机有多个LID(每个端口一个)。

3.2 LID分配机制:谁说了算?

LID的分配不是随意的,也不是手动配的(虽然可以手动配,但我强烈不建议)。在IB子网里,有一个叫子网管理器(Subnet Manager,简称SM)的角色,它负责给所有端口分配LID。

分配流程大概是这样的:

  1. 发现阶段:SM通过SMP(子网管理包)扫描所有设备,发现每个端口。
  2. 分配阶段:SM给每个端口分配一个唯一的LID。默认情况下,每个端口只分配一个LID。
  3. 通告阶段:SM把LID信息写入端口的本地寄存器,同时更新交换机的转发表。

我个人习惯在调试时用 ibstat 命令查看LID分配情况。比如:

# 查看所有IB端口的LID信息
ibstat

# 输出示例:
# CA 'mlx5_0'
#         Port 1:
#                 State: Active
#                 Physical state: LinkUp
#                 Rate: 100
#                 Base lid: 0x2
#                 LMC: 0
#                 LID: 0x2

这里有个概念叫LMC(LID Mask Control),它决定了一个端口可以有多少个LID。LMC=0表示只有一个LID,LMC=1表示有两个LID(0x2和0x3),以此类推。多LID主要用于多路径负载均衡,咱们后面章节会详细讲。

避坑指南:我曾经在一个生产环境里,因为误把LMC设成了2,导致一个端口有4个LID。结果路由表爆炸了,交换机内存不够用。嗯,LMC这东西,不是越大越好,够用就行。

3.3 单一路径转发原理:数据包怎么走?

有了LID,数据包就能找到路了。但具体怎么走?这就要说到IB交换机的转发机制。

每个IB交换机内部有一张线性转发表(Linear Forwarding Table,简称LFT)。这张表的结构很简单:

LID(目的) 出端口
0x0001 Port 3
0x0002 Port 5
0x0003 Port 2
... ...

当数据包到达交换机时,交换机会提取包头的目的LID,然后查LFT,找到对应的出端口,直接转发出去。整个过程是线性的,没有路由计算,没有最长前缀匹配,就是简单的查表。

你想想看,这跟以太网的MAC地址表有点像,但更简单。以太网还要学MAC地址,IB的LFT是SM直接写死的,交换机自己不做学习。

转发流程:

  1. 源端发送数据包,目的LID设为0x2
  2. 第一跳交换机收到包,查LFT:0x2 → Port 5
  3. 从Port 5转发出去
  4. 下一跳交换机继续查表转发
  5. 直到到达目的端口

这里有个细节:IB的转发是基于LID的逐跳转发。每个交换机只关心下一跳,不关心整条路径。这跟IP路由的逐跳转发是一个道理。

3.4 线性转发表(LFT)结构:一张表走天下

LFT的结构其实很简单,但它的设计有一些巧妙之处。

首先,LFT是一个线性数组,数组下标就是LID值。比如LID=0x2,就直接查数组第2个元素。这种设计的好处是查找速度极快,O(1)时间复杂度。

其次,LFT的条目数等于交换机支持的LID范围。一般来说,IB交换机支持0x0000到0xBFFF,也就是49152个条目。每个条目存储一个出端口号(8位或16位,取决于交换机实现)。

我见过有人问:为什么不用哈希表?嗯,哈希表有冲突,有查找开销。IB交换机是硬件转发,要求每个包都在纳秒级别完成查表。线性数组是最快的,没有之一。

LFT的更新由SM负责。当网络拓扑变化时(比如新设备加入、链路断开),SM会重新计算路由,然后通过SMP把新的LFT写入交换机。这个过程叫路由重计算

注意:LFT更新期间,交换机可能会丢包。因为旧的LFT还在用,新的LFT还没生效。SM通常会采用「先写后删」的策略,尽量减少丢包。但如果你在做在线业务,最好在低峰期进行拓扑变更。

咱们来看一个实际的LFT例子。假设有一个8端口交换机,SM分配了如下LFT:

LID    Port
0x0001  1
0x0002  2
0x0003  3
0x0004  4
0x0005  5
0x0006  6
0x0007  7
0x0008  8
0x0009  1
0x000A  2
...

你会发现,LID和端口不是一一对应的。同一个端口可以对应多个LID(比如Port 1对应0x0001和0x0009)。这就是多路径的基础——通过不同的LID,让流量走不同的路径。

嗯,这里埋个伏笔。多路径路由的核心就是利用LMC和LFT,让同一个目的端口有多个LID,每个LID对应一条不同的路径。咱们后面章节会详细展开。

3.5 实战小贴士:如何排查LID问题?

最后,分享几个我在项目中常用的排查命令:

  • ibroute -n <lid>:查看某个LID的转发路径
  • ibswitches:查看所有交换机的LID和端口信息
  • iblinkinfo:查看链路状态和LID
  • smpquery:直接查询SM的配置信息

我曾经遇到过一个诡异的问题:两个节点ping不通,但ibstat显示链路正常。查了半天,发现是SM给其中一个端口分配了重复的LID。嗯,SM也有bug的时候。重启SM后问题解决。

所以,遇到LID相关的问题,第一步永远是确认LID是否唯一、是否有效。别一上来就怀疑硬件。

好了,这一讲就到这里。LID是IB网络的基石,理解透了,后面的多路径、负载均衡才能玩得转。下一讲咱们聊聊路径计算和路由算法,敬请期待。