从存储架构到InfiniBand:深入理解网络存储与高性能流控机制
一、存储架构的基石:DAS、NAS 与 SAN
在构建企业级IT基础设施时,理解三种基本的存储架构是第一步。
- DAS(直连存储):存储设备直接挂载在一台服务器上,使用 SATA、SAS、USB 或 Thunderbolt 线缆。它简单、便宜,但无法跨机共享,容易形成“存储孤岛”。
- NAS(网络附加存储):通过以太网络提供文件级共享(NFS、SMB),使用标准的双绞线或光纤以太网线。它便于多用户访问,但性能受网络延迟影响。
- SAN(存储区域网络):构建专用的高速存储网络,服务器看到的是块设备。SAN 可采用光纤通道(FC)、iSCSI 或 InfiniBand 等协议,其中光纤通道使用专用的 FC 光纤线,而 InfiniBand 则使用专用的 IB 线缆或光纤。
二、接口与协议的迷宫:SAS、FC 与 InfiniBand
初学者容易混淆的术语包括:
- SAS(串行连接SCSI):是一种接口技术,而非存储架构。它用于连接硬盘与服务器,支持双端口、高可靠,常见于企业级 DAS 或 SAN 内部的磁盘柜。SAS 线缆外观类似 SATA,但协议更健壮。
- FC(光纤通道):是一种网络协议,专为 SAN 设计。它使用光纤作为物理介质,但协议栈与以太网完全不同。光纤通道的“光纤”指传输介质,而“通道”强调其存储专用属性。它并不等同于“光纤以太网口”。
- InfiniBand(IB):另一种高性能网络协议,面向超算和 AI 集群。它也可以使用光纤或铜缆,但其协议栈、交换机制和流控方式均独立于 FC 和以太网。
三、为什么 InfiniBand 是 AI 训练的标配?
当前 AI 大模型训练需要连接成千上万块 GPU。尽管以太网已能实现 1.6 Tbps 的单端口速率,但 InfiniBand 仍占据主导地位。原因在于:
- 极低的延迟:InfiniBand 端到端延迟可低至 100 纳秒级,而 RoCEv2(基于以太网的 RDMA)通常在 1-5 微秒。
- 无损流控:InfiniBand 采用基于信用的流控(CBFC),从源头杜绝丢包。以太网即使使用 PFC(优先级流控)也仍存在丢包风险,导致重传和性能抖动。
- 拥塞控制更优:CBFC 的“预约制”配合自适应路由,让数据流永远不堵车。而以太网的反应式拥塞控制(ECN、PFC)在突发流量下容易形成“拥塞树”,拖慢整体训练速度。
- 网络内计算:InfiniBand 交换机支持 SHARP 技术,可将 All-Reduce 等集体通信卸载到交换机,大幅减少 GPU 等待时间。
- 软硬一体生态:英伟达的 NCCL 库与 InfiniBand 深度绑定,开箱即用,而以太网方案需要额外调优。
四、InfiniBand 低延迟的核心:基于信用的流控(CBFC)
4.1 工作机制
CBFC 是一种“先预约,后发送”的链路级流控。其原理如下:
- 接收端通过专用的硬件缓冲区为每个发送端维护一个信用账户。
- 发送端每发送一个 64 字节的数据块(一个流控块),就消耗一个信用。
- 当信用耗尽,发送端必须停止发送,直到收到接收端返回的信用更新(表示接收端已处理完数据,释放了缓冲区)。
- 该过程完全由硬件(HCA 网卡和交换机)自动完成,不占用 CPU 资源。
4.2 硬件实现 vs 软件辅助
CBFC 的核心逻辑固化在硬件中,但需要软件进行初始配置和管理:
- 硬件层面:网卡负责信用的增减、数据包的重传、ACK 信令的生成;交换机执行直通转发和基于信用的端口仲裁。
- 软件层面:子网管理器(SM)负责拓扑发现、路由计算和初始化信用配额;驱动程序通过 Verbs API 设置 QP 深度、RNR 重试参数等。
4.3 CBFC 与 RNR NAK
在可靠连接(RC)模式下,如果接收端的接收请求(Receive Request)耗尽,硬件会返回一个 RNR NAK 包,告知发送端“接收方未就绪”。发送端会根据预设的重试策略(retry_count 和 rnr_timer)自动重试。重试次数过多会导致微秒级的暂停,影响性能。因此编程时需要合理配置 QP 的接收队列深度(max_recv_wr)并确保应用程序及时 post_recv。
五、CBFC 软件编程实践
5.1 应用层信用跟踪(C 语言伪代码)
struct sender_context {
struct rdma_cm_id *id;
int remote_credits; // 应用层跟踪的信用额度
pthread_mutex_t lock;
pthread_cond_t cond;
};
void send_data(struct sender_context *ctx, const char *buf, size_t len) {
pthread_mutex_lock(&ctx->lock);
while (ctx->remote_credits <= 0) // 无信用则等待
pthread_cond_wait(&ctx->cond, &ctx->lock);
ctx->remote_credits--;
pthread_mutex_unlock(&ctx->lock);
// 构造 SEND WR 并 ibv_post_send ...
}
void handle_completion(struct sender_context *ctx, struct ibv_wc *wc) {
if (wc->opcode == IBV_WC_RECV) { // 收到接收端释放信用的消息
pthread_mutex_lock(&ctx->lock);
ctx->remote_credits++;
pthread_cond_signal(&ctx->cond);
pthread_mutex_unlock(&ctx->lock);
}
}
5.2 接收端持续发布接收请求
void post_recv_buffer(struct receive_context *ctx, void *buf, size_t len) {
struct ibv_recv_wr wr = {0};
// 设置 sge ...
if (ibv_post_recv(ctx->id->qp, &wr, &bad_wr))
// 错误处理:若频繁失败,表明接收队列深度不足或处理过慢
}
void on_message_received(..., void *recv_buf) {
process_data(recv_buf);
post_recv_buffer(ctx, recv_buf, BUFFER_SIZE); // 立即归还信用
send_credit_update_to_sender(ctx); // 可选:通知发送端
}
5.3 关键参数配置
- QP 队列深度:
max_send_wr和max_recv_wr直接影响信用容量。 - RNR 重试参数:通过
rdma_set_option设置retry_count和rnr_timer(通常设为 7 和 20,避免无限等待)。
六、Perftest 中的 CBFC 体现
ib_send_bw 和 ib_write_bw 是官方性能测试工具,它们并未手动操作信用值,而是通过以下方式利用了 CBFC:
- 配置队列深度:
-r(rx_depth)参数决定了接收端预先发布的接收请求数量,即初始信用总额。-d(tx_depth)决定发送端并发能力。 - 循环中及时 repost:收到完成事件后立即重新发布接收请求,持续产生新信用,避免 RNR NAK。
- 传递重试策略:通过
rdma_cm设置 RNR 重试次数和超时,使硬件在信用暂时不足时自动重试,保证吞吐量。 - 统计计数器:工具会读取硬件计数器,如
rnr_retry_count,帮助用户判断是否存在接收端处理瓶颈。
七、总结
从 DAS/NAS/SAN 的架构区分,到 SAS、FC、InfiniBand 的协议对比,再深入到 InfiniBand 基于信用的流控机制,我们看到了现代数据中心为了实现极低延迟和高吞吐所做出的精巧设计。CBFC 作为 InfiniBand 低延迟的基石,其硬件实现的信用预约机制、与 RNR NAK 的协同、以及应用层的编程范式,共同构成了一个完整的高性能网络闭环。当前,虽然以太网正通过 UEC 联盟等技术奋起直追,但在 AI 大模型训练的万卡连接场景中,InfiniBand 依然凭借其成熟的无损流控和网络内计算能力,保持着不可替代的地位。
从存储入门到 InfiniBand 核心:一文搞懂 DAS/NAS/SAN、SAS/FC/IB 以及基于信用的流控
暑假学习网络存储,顺便把 AI 训练背后的高速互联技术也捋清楚了
目录
- 1. 存储架构三兄弟:DAS、NAS、SAN
- 2. 容易混淆的接口与协议:SAS、FC、InfiniBand
- 3. 为什么 AI 训练首选 InfiniBand?
- 4. InfiniBand 极低延迟的秘密:基于信用的流控 (CBFC)
- 5. CBFC 编程实践(C 语言示例)
- 6. perftest 中的 CBFC:ib_send_bw / ib_write_bw 是如何利用它的?
- 7. 总结与展望
1. 存储架构三兄弟:DAS、NAS、SAN
无论是搭建家庭媒体中心还是设计数据中心,首先需要搞懂三种基本的存储架构。
| 类型 | 全称 | 连接方式 | 典型线缆 | 特点 |
|---|---|---|---|---|
| DAS | Direct Attached Storage | 直连服务器/PC | SATA、SAS、USB、Thunderbolt | 简单、便宜,但无法共享,形成存储孤岛 |
| NAS | Network Attached Storage | 接入以太网 | 双绞线(RJ45)、光纤以太网 | 文件级共享(NFS/SMB),便于多用户,但性能受网络影响 |
| SAN | Storage Area Network | 专用存储网络 | 光纤(FC)、以太网(iSCSI)、InfiniBand 线缆 | 块级共享,高性能、高可靠,但成本高、管理复杂 |
一句话总结:DAS 是私有硬盘,NAS 是共享文件夹,SAN 是远程虚拟硬盘。
2. 容易混淆的接口与协议:SAS、FC、InfiniBand
很多初学者会把 SAS、FC、InfiniBand 混为一谈,甚至认为“光纤通道就是光纤网口”。这里作一次彻底澄清。
🔹 SAS(Serial Attached SCSI)
- 本质:硬盘接口技术,不是网络架构。
- 特点:企业级,双端口,7×24 小时高可靠,速率 12/24 Gbps。
- 用途:用于 DAS 内部连接硬盘,或作为 SAN 磁盘柜的后端接口。
- 与 SATA 区别:SAS 控制器可以同时连接 SAS 和 SATA 硬盘,反之不行。
🔹 FC(Fibre Channel,光纤通道)
- 本质:存储专用网络协议,用于 SAN。
- 特点:无损、低延迟,使用专用交换机(如 Brocade),独立于以太网。
- 误区:光纤通道虽然常用光纤作为介质,但和“光纤以太网口”完全不是一回事。前者跑 FC 协议,后者跑以太网协议,二者不兼容。
- 速率:当前主流 32/64 GFC,第八代达 128 GFC。
🔹 InfiniBand(IB)
- 本质:高性能计算 / AI 集群专用网络协议。
- 特点:极低延迟(100 纳秒级)、基于信用的流控、网络内计算(SHARP)。
- 介质:可使用光纤或铜缆,但物理层协议与 FC、以太网均不同。
- 速率:NDR 800 Gbps,XDR 1.6 Tbps 已在路上。
3. 为什么 AI 训练首选 InfiniBand?
当前 AI 大模型训练需要连接成千上万块 GPU。虽然以太网单端口速率已达 1.6 Tbps,但在万卡集群中,InfiniBand 依然是标配。原因如下:
- 极低且稳定的延迟:InfiniBand 端到端延迟 ~100 ns,而 RoCEv2 通常为 1–5 μs(且尾延迟高)。
- 无损流控:CBFC 从源头杜绝丢包。以太网的 PFC(优先级流控)在某些拥塞场景下仍可能丢包,导致重传和性能崩塌。
- 自适应路由:IB 交换机可为每个数据包动态选择最优路径;以太网通常使用静态 ECMP,容易哈希不均造成拥塞。
- 网络内计算:IB 支持 SHARP 技术,将 All-Reduce 等集体通信卸载到交换机,减少 GPU 等待时间。
- 生态封闭但高效:英伟达 NCCL 库与 InfiniBand 深度绑定,开箱即得最优性能。
尽管 UEC(超以太网联盟)正在为以太网引入类似 IB 的机制,但在最顶级的超算和 AI 集群中,InfiniBand 目前仍是王者。
4. InfiniBand 极低延迟的秘密:基于信用的流控 (CBFC)
InfiniBand 的低延迟并非只靠高带宽,其核心是 Credit‑Based Flow Control。
4.1 CBFC 工作原理
CBFC 是一种“先预约,后发送”的链路级流控,完全由硬件自动执行:
- 接收端为每个发送端维护一个 信用账户,初始值等于接收缓冲区大小(按 64 字节为一个信用单位)。
- 发送端每发送一个 64 字节的数据块,就消耗一个信用。
- 当信用耗尽,发送端必须立即停止发送,直到收到新的信用。
- 接收端每处理完一个数据块(并释放缓冲区),会自动向发送端返回一个“信用更新”包。
- 整个过程由网卡(HCA)和交换机硬件完成,不消耗 CPU。
类比:信用就像停车位。你必须有空位才能停车;车开走后空位才释放。
4.2 硬件实现 vs 软件辅助
虽然 CBFC 是硬件实现的,但软件需要完成以下配置:
- 队列深度:通过
max_send_wr和max_recv_wr间接影响可用信用总量。 - RNR 重试参数:
retry_count和rnr_timer,决定发送端收到 “接收方未就绪” 时的重试行为。 - 子网管理:子网管理器(SM)负责初始化信用配额、路由计算。
4.3 RNR NAK 与重试策略
在可靠连接(RC)模式下,如果接收端的接收请求(Receive Request)耗尽,硬件会返回一个 RNR NAK(Receiver Not Ready)。发送端根据预设的重试策略自动重试。
retry_count = 7(最大):硬件会无限重试,但每次重试会有一定延迟(由rnr_timer决定)。retry_count = 0:不重试,直接报错,适合对延迟极度敏感的应用。
编程注意事项:
- 接收端必须及时且持续地发布新的接收请求(
ibv_post_recv),避免 RNR NAK。 - QP 的
max_recv_wr不宜太小(建议至少 1024)。
5. CBFC 编程实践(C 语言示例)
以下示例基于 libibverbs 和 librdmacm,展示如何在应用层跟踪信用,并正确处理 RNR NAK。
5.1 发送端:应用层信用跟踪
#include <rdma/rdma_cma.h>
#include <pthread.h>
struct sender_context {
struct rdma_cm_id *id;
int remote_credits; // 应用层跟踪的信用数量
pthread_mutex_t lock;
pthread_cond_t cond;
};
// 发送数据(非阻塞方式)
void send_data(struct sender_context *ctx, const char *buf, size_t len) {
struct ibv_send_wr wr, *bad_wr;
struct ibv_sge sge;
pthread_mutex_lock(&ctx->lock);
// 核心:无信用则等待
while (ctx->remote_credits <= 0) {
pthread_cond_wait(&ctx->cond, &ctx->lock);
}
ctx->remote_credits--;
pthread_mutex_unlock(&ctx->lock);
// 构造 SEND WR(省略 sge 初始化)
memset(&wr, 0, sizeof(wr));
wr.opcode = IBV_WR_SEND;
wr.sg_list = &sge;
wr.num_sge = 1;
wr.send_flags = IBV_SEND_SIGNALED;
if (ibv_post_send(ctx->id->qp, &wr, &bad_wr)) {
perror("ibv_post_send failed");
}
}
// 在完成队列(CQ)处理函数中更新信用
void handle_completion(struct sender_context *ctx, struct ibv_wc *wc) {
if (wc->opcode == IBV_WC_RECV) {
// 收到接收端返回的信用更新消息
pthread_mutex_lock(&ctx->lock);
ctx->remote_credits++;
pthread_cond_signal(&ctx->cond); // 唤醒可能等待的发送线程
pthread_mutex_unlock(&ctx->lock);
}
}
5.2 接收端:持续发布接收请求
struct receive_context {
struct rdma_cm_id *id;
struct ibv_mr *mr;
int max_recv_wr; // 接收队列深度
};
void post_recv_buffer(struct receive_context *ctx, void *buf, size_t len) {
struct ibv_recv_wr wr, *bad_wr;
struct ibv_sge sge;
memset(&wr, 0, sizeof(wr));
sge.addr = (uintptr_t)buf;
sge.length = len;
sge.lkey = ctx->mr->lkey;
wr.sg_list = &sge;
wr.num_sge = 1;
if (ibv_post_recv(ctx->id->qp, &wr, &bad_wr)) {
fprintf(stderr, "Failed to post recv buffer -- RNR NAK may occur!\n");
exit(1);
}
}
void on_message_received(struct receive_context *ctx, void *recv_buf) {
// 1. 处理数据
process_data(recv_buf);
// 2. 立即重新发布接收请求,归还一个信用(关键!)
post_recv_buffer(ctx, recv_buf, BUFFER_SIZE);
// 3. 可选:显式通知发送端信用已释放
send_credit_update_to_sender(ctx);
}
5.3 关键参数配置
// 在创建 QP 时设置队列深度
struct ibv_qp_init_attr qp_init_attr = {
.send_cq = cq,
.recv_cq = cq,
.qp_type = IBV_QPT_RC,
.cap = {
.max_send_wr = 1024, // 发送队列深度
.max_recv_wr = 1024, // 接收队列深度(直接影响信用容量)
.max_send_sge = 1,
.max_recv_sge = 1,
},
};
// 通过 rdma_cm 设置 RNR 重试参数(连接前)
int rnr_retry = 7; // 无限重试
int timeout = 20; // 重试超时 = 20 * 4.096 μs ≈ 81.92 μs
rdma_set_option(id, RDMA_OPTION_ID, RDMA_OPTION_ID_RNR_RETRY,
&rnr_retry, sizeof(rnr_retry));
rdma_set_option(id, RDMA_OPTION_ID, RDMA_OPTION_ID_TIMEOUT,
&timeout, sizeof(timeout));
6. perftest 中的 CBFC:ib_send_bw / ib_write_bw 是如何利用它的?
ib_send_bw 和 ib_write_bw 是官方 RDMA 性能测试工具。它们没有“手动”操作信用,而是通过以下方式与 CBFC 协同工作:
- 配置队列深度:
-r(rx_depth)参数决定接收端预先发布的 Receive Request 数量,即初始信用总额。例如-r 2048意味着发送端最多可以有 2048 个未完成的消息。 - 循环中立即 repost:工具的主循环在收到完成事件后,会立刻调用
repost_receive_buffers(),源源不断地归还信用,避免 RNR NAK。 - 传递重试策略:通过
rdma_cm设置rnr_retry和timeout参数,使得在极少数信用不足时硬件自动重试,确保测试不中断。 - 统计计数器:工具通过
ibv_query_port等接口读取硬件计数器,如rnr_retry_count,如果该值过高,说明接收端处理能力不足或队列深度太小。
一句话:perftest 是 CBFC 的模范用户——它通过合理的参数和编程模式,让硬件流控发挥最大效能。
7. 总结与展望
从基础的 DAS/NAS/SAN 架构,到 SAS、FC、InfiniBand 的协议辨析,再到 InfiniBand 基于信用的流控机制,我们一步步揭示了现代数据中心如何实现极低延迟和高吞吐。
核心 takeaways
- DAS、NAS、SAN 分别对应直连、文件共享、块级专用网络,选型取决于数据共享需求、性能要求和预算。
- SAS 是硬盘接口,FC 是存储专用网络,InfiniBand 是超算/AI 专用网络——三者不能混为一谈。
- InfiniBand 的低延迟 主要归功于硬件实现的 CBFC(基于信用的流控),配合自适应路由和网络内计算,使其成为 AI 训练的首选。
- CBFC 编程 时需注意:接收端必须及时
post_recv,合理设置队列深度和 RNR 重试参数,并在应用层可选跟踪信用以实现更好的非阻塞控制。 - perftest 工具 通过
-r参数和控制循环,完美展示了如何利用 CBFC 进行高性能基准测试。
未来趋势
- 以太网阵营正在通过 UEC(超以太网联盟) 引入类似 IB 的信用流控和遥测机制,力争在 AI 集群中取代 InfiniBand。
- InfiniBand 则继续向 XDR(1.6 Tbps)迈进,并持续优化 SHARP 等网络内计算特性。
- 对于普通开发者,理解 CBFC 的原理不仅能帮你写出更高效的 RDMA 程序,也能帮助你读懂
perftest的调优参数。
希望这篇文章能成为你学习网络存储和高性能互连的一份实用笔记。如有不对之处,欢迎指正交流!
📌 本文所有代码示例均为基于
libibverbs/librdmacm的伪代码,生产环境中请结合错误处理和资源管理进一步完善。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)