跳到主要内容
新型互联与远程内存

第8章:端到端实战 —— 在 RDMA 集群上跑 DM 事务 / KV-Cache 池

从零搭一个 RDMA 集群环境(CloudLab / 自建),装 OFED,跑 CREST + AdaptX 实测 1.91× 加速,以及 Mooncake KV-cache 池 demo。完整 troubleshooting

实战 CloudLab OFED CREST AdaptX Mooncake RDMA setup

前面七章把概念和论文吃透了,这一章下场跑代码——在真实 RDMA 集群上把一套 DM 事务系统(CREST + AdaptX)和一套 KV-cache 池(Mooncake demo)从零跑通。包括 CloudLab 集群申请、OFED 驱动安装、ConnectX 网卡识别、跑通 Loop A 拿到 1.91× 复现数据、以及完整的 troubleshooting 清单。读完这章你会有 可以放进简历的 RDMA 实战经验,也能避开 90% 的新人坑(memcached 绑 127.0.0.1、IOMMU 没设 passthrough、MR 溢出导致内核 panic 之类的事故)。

📑 目录


1. 选 RDMA 集群:CloudLab vs 自建 vs 商业云

选项价格上手难度灵活度适合场景
CloudLab免费(学术)中(profile 限定)论文复现、研究实验、本系列推荐
自建高(单机数万)极高长期实验室基础设施
Azure HBv4 / AWS p5 / GCP A3贵(按小时)中(云厂方案)工业 PoC、对照实验

CloudLab 优劣:

  • ✅ 免费(学术账号),申请通过即用
  • ✅ 多 profile 可选(small-lan / xl170 等),自带 RDMA 硬件
  • ❌ 高峰期抢机器(尤其 c6525 系列),实验时间限制(默认 16h,要 extend)
  • ❌ 控制网络受限,不能跑高流量

自建优劣:

  • ✅ 完全控制,长期可用
  • ❌ 单卡 ConnectX-6 100GbE ~¥10K,加交换机 ~¥30K,起步成本高
  • ❌ 需要自己装 OS / OFED / 调网络,没人手工程负担大

商业云优劣:

  • ✅ 即开即用、规模可大
  • ❌ 贵(p5.48xlarge 一小时几十美元),长期实验吃不消
  • ❌ RDMA 接口往往是定制(EFA/SRD),不是标准 verbs,需要适配

🌟 本系列推荐:CloudLab 起步,自建作为长期投入。本章用 CloudLab 作为实战平台。

2. CloudLab 实战:申请 small-lan profile + ConnectX-6 配置

注册流程:

  1. 访问 cloudlab.us,注册学术账号(用 .edu 邮箱)
  2. 加入或创建 project,等管理员批准(通常一两天)
  3. 上传 SSH public key 到个人设置

实例化 small-lan profile:

Profile: small-lan
Hardware:  c6525-25g (5 节点 + ConnectX-6 Dx 100GbE)
Cluster:   Utah (推荐, 资源最多)
Duration:  16 hours (default, 可申请延长)

申请提交后等几分钟,到 List View 看节点 hostname,典型如 amd103.utah.cloudlab.us

SSH 进入 (用 ~/.ssh/cloudlab 私钥):

ssh -i ~/.ssh/cloudlab chaomei@amd103.utah.cloudlab.us

关键经验:

  • mlx5_2 是实验网络 NIC,绑定 ens1f0 (10.10.1.x 子网,实验内部互通,RDMA 数据流量必走这个)
  • mlx5_0 是 control 网络(对应物理口 eno33,绑定 128.110.x 公网 IP)。禁止用 mlx5_0 跑 RDMA 大流量——会被 CloudLab 检测系统警告 / 强制停实验
  • 节点间 ICMP 互通(用 10.10.1.x ping 邻居),SSH 跳板可省

⚠️ 极重要:本系列踩过的所有性能问题,第一时间检查的就是”用对了 mlx5_2 没”。代码里 ib_dev_id 必须设 2 或代码硬指定 mlx5_2,不是 0。

3. OFED 安装与网卡验证

CloudLab Ubuntu 22.04 的发行版 inbox driver 在某些 verbs 上不全(尤其 ibv_exp_* extended verbs,CREST 依赖)。必须装 Mellanox OFED:

# 选合适版本(本系列实测用 4.9-7.1.0.0,与 ConnectX-6 + Ubuntu 22.04 兼容)
wget https://content.mellanox.com/ofed/MLNX_OFED-4.9-7.1.0.0/MLNX_OFED_LINUX-4.9-7.1.0.0-ubuntu22.04-x86_64.tgz
tar xf MLNX_OFED_LINUX-4.9-7.1.0.0-ubuntu22.04-x86_64.tgz
cd MLNX_OFED_LINUX-4.9-7.1.0.0-ubuntu22.04-x86_64
sudo ./mlnxofedinstall --upstream-libs --dpdk

# 重启网卡服务
sudo /etc/init.d/openibd restart

验证安装:

# 看到 4 张设备(mlx5_0 ~ mlx5_3)
ibv_devinfo -d mlx5_2

# 关键字段:
# - active_mtu: 应为 1024 或 4096(默认可能 256, 太小)
# - state: PORT_ACTIVE
# - phys_state: LINK_UP

MTU 调整(active_mtu 默认低,得调大):

# 临时改(到 mtu 4096):
sudo ifconfig ens1f0 mtu 4202   # 这是 ethernet 层 MTU,Larger 是为了容纳 IB header
# 或代码里直接指定 IBV_MTU_4096(本系列代码改过此处)

⚠️ IOMMU passthrough 是必须的:CloudLab 默认 iommu=pt 没开,会导致 RDMA READ 返回全 0(WC 状态显示 SUCCESS 但内容错)。

sudo vi /etc/default/grub
# 找到 GRUB_CMDLINE_LINUX_DEFAULT,加上 iommu=pt
# 例: GRUB_CMDLINE_LINUX_DEFAULT="quiet splash iommu=pt"

sudo update-grub
sudo reboot

4. 跑通 perftest:Hello World RDMA

OFED 装好后用 perftest 三板斧验证 RDMA 通路:

# 节点 A (server, 假设是 amd103, 实验 IP 10.10.1.3)
ib_read_bw -d mlx5_2 -i 1 -F --report_gbits

# 节点 B (client, 用 A 的实验 IP 10.10.1.3)
ib_read_bw -d mlx5_2 -i 1 -F --report_gbits 10.10.1.3

预期输出(ConnectX-6 Dx 100GbE):

 #bytes     #iterations    BW peak[Gb/sec]    BW average[Gb/sec]
 65536      5000           94.83              94.65

跑过 90 Gb/s 算正常。低于 80 Gb/s 检查:

  • MTU 是否调到 1024+(默认 256 性能腰斩)
  • 是不是用错了 mlx5_0(control 网,只 1 Gb/s)
  • PFC / ECN 配置(默认 CloudLab 配置已 OK,自建集群可能要手调)

ib_atomic_bw 单独跑(测 CAS IOPS,DM 事务关键):

ib_atomic_bw -d mlx5_2 -i 1 -F -A CMP_AND_SWP

ConnectX-6 期望 5-10 M ops/s,这是 DM 事务系统理论的 atomic 上限。

5. 跑 CREST + AdaptX:复现 Loop A 1.91× 数据

CREST 是本系列的实验载体。3-CN 1-MN 拓扑(MN=amd103, CN0=amd118, CN1=amd107, CN2=amd112):

# 在所有节点上 clone CREST + AdaptX patch
git clone <crest-repo> /users/chaomei/CREST-Opensource-0007
cd /users/chaomei/CREST-Opensource-0007

# 应用 AdaptX patch(LoopA + LoopB)
git apply ../adaptx.patch

# Build
mkdir build && cd build
cmake -DCMAKE_BUILD_TYPE=Release ..
make -j40

配置文件(config/cloudlab_tpcc_3cn.json):

{
  "MN_ips": ["10.10.1.3"],
  "CN_ips": ["10.10.1.4", "10.10.1.2", "10.10.1.5"],
  "ib_dev_id": 2,
  "ib_port": 1,
  "gid_idx": 3,
  "mr_size": 32,
  "memcached_ip": "10.10.1.3"
}

⚠️ 必须手动启 memcached(systemd 起的版本绑 127.0.0.1,CN 远程连不上):

# 在 MN (amd103) 上
sudo systemctl stop memcached
memcached -d -p 11211 -u chaomei -m 256 -c 1024 -l 0.0.0.0
ss -tlnp | grep 11211    # 验证: 应该显示 0.0.0.0:11211

跑 baseline:

# MN
cd /users/chaomei/CREST-Opensource-0007/build/benchmark
./bench_runner --role=mn --config=cloudlab_tpcc_3cn.json --workload=tpcc

# 在每个 CN
./bench_runner --role=cn --config=cloudlab_tpcc_3cn.json --workload=tpcc \
               --threads=28 --coros=3 --duration=60

记录 thpt 数字(Kops/s)。

跑 Loop A(同一拓扑,加 --loop_a):

./bench_runner --role=cn --config=cloudlab_tpcc_3cn.json --workload=tpcc \
               --threads=28 --coros=3 --duration=60 \
               --loop_a --loop_a_ai_step=4 --loop_a_nf=2

预期数字:在 extreme regime(1/40 仓库 95% hot)下,Loop A vs baseline 应该看到 1.91× thpt。在 uniform 下接近 1.0×(无副作用)。

反例复现 — alt-extreme regime(2/40 仓库 92% hot):

# 改 workload 配置成 alt-extreme(具体见 caesar/data/loopa_alt/)
./bench_runner --role=cn --workload=tpcc_alt_extreme \
               --loop_a   # 应该看到 ~0.87× baseline (regression)

🌟 这个反例是 AdaptX 论文 §6.4 的关键 “critical control” —— 证明 Loop A 不是 universal good,signal trigger 在某些 regime 下会误调。

6. 跑 Mooncake KV-Cache 池 demo

Mooncake transfer engine 开源版相对独立,可以单跑 KV blocks 搬运 demo:

git clone https://github.com/kvcache-ai/Mooncake
cd Mooncake/transfer_engine

# Build (依赖 RDMA + protobuf)
mkdir build && cd build
cmake .. && make -j

# Master 节点(管理 KV pool 元数据)
./mooncake_master --port=12345 --bind=10.10.1.3

# Worker 1 (有 KV blocks)
./mooncake_worker --master=10.10.1.3:12345 --rdma-dev=mlx5_2 --bind=10.10.1.4

# Worker 2 (拉取 KV blocks)
./mooncake_worker --master=10.10.1.3:12345 --rdma-dev=mlx5_2 --bind=10.10.1.5

测试程序(用 dummy KV blob 测延迟带宽):

# 从 worker 1 push 一个 4MB blob
./bench_kv_transfer --src=10.10.1.4 --dst=10.10.1.5 --size=4M --ops=1000

# 期望:
#   单次 push 延迟 ~50-80 µs (4MB on 100GbE)
#   总带宽 ~80-90 Gb/s

⚠️ 2026 视角:Mooncake 开源版本本进展速度很快,具体接口可能与本节命令略有出入。以官方 README 为准,本节展示 mental model(master + worker + transfer)。

7. 完整 Troubleshooting 清单

本系列在 CloudLab 上踩过的坑(都是真实事故):

7.1 “RDMA reads return zero”(成功完成但内容全 0)

  • 原因:IOMMU 没设 passthrough
  • 解决:/etc/default/grubiommu=ptupdate-grubreboot

7.2 “Memcached connection refused”

  • 原因:systemd 起的 memcached 绑 127.0.0.1
  • 解决:停掉默认服务,手动起 memcached -l 0.0.0.0

7.3 “MR allocation failed” 或节点 panic

  • 原因:mr_size 配太大,populate 时 MR 申请超过物理内存
  • 解决:本系列改了 CREST 默认 MAX_PAYMENT_CNT=100, MAX_ORDERID=3000,把 TPC-C 数据从 38 GB 压到 5.2 GB,mr_size=16 就够。Config 中 mr_size 不要轻易调大

7.4 “Connection timeout”(SSH 进不去 CloudLab)

  • 原因:Clash TUN 模式劫持所有 TCP
  • 解决1:关闭 Clash TUN
  • 解决2:Clash 规则最前面加 IP-CIDR,128.110.219.0/24,DIRECT
  • 诊断:ping 通但 SSH 不通 → 99% 是 TCP 被劫持

7.5 “Cluster panic during populate”(节点直接挂死)

  • 原因:MR 溢出杀内核(尤其 amd119 / amd112 这两台老节点)
  • 解决:换稳定节点(amd103, amd118 实测稳定);populate 前用小 hash 表试,看是否能通过

7.6 “ib_dev_id wrong”(thpt 只有 1/100 期望)

  • 原因:用了 mlx5_0(control 网, 1Gbps 限制)而不是 mlx5_2(实验网, 100Gbps)
  • 解决:确认 config 中 ib_dev_id=2,代码中所有 ibv_open_device 调用确认走 index 2

7.7 “Sync timeout”(多 CN 启动后某个 CN 卡住)

  • 原因:Config 中 CN 数量与实际启动不一致(SyncComputeNodes 等不到全员)
  • 解决:Config 中 CN 数 = 实际启动 CN 数,严格相等

7.8 “atomic IOPS 低于 1M”(CAS 慢得离谱)

  • 原因:NIC 走了 software emulation(老固件 / 配置问题)
  • 解决:mlxconfig 看 NIC 配置,确认 ATS_ENABLED=1 和 atomic offload 启用

核心 5 大坑总结:IOMMU、memcached、MR、TUN 劫持、wrong dev_id——把这 5 个 check 走一遍,90% 的初次部署问题就清了。

8. 下一步:把实战做成研究方向

跑通 baseline + Loop A 之后,如何转向研究?三条路:

8.1 在 CREST 上做改造(系统研究)

  • Per-key admission:Loop A 现在是 worker 粒度,改成 per-hot-key 粒度,看 alt-extreme regime 是否能从 0.87× 翻到 >1×
  • Loop C(新环路):加一个基于 PCIe utilization 的环路(signal=PCIe 使用率,actuator=batch size),验证 ⟨S, A, R, C⟩ composition 框架的可扩展性
  • ATC / SOSP / NSDI 系统会议

8.2 跨硬件验证(实证研究)

  • 在自建集群(InfiniBand 而不是 RoCE)上重跑 Loop A,看反应窗口能否更紧
  • 在 ConnectX-7(下一代)上重做,看 atomic IOPS 上限是否真的提升
  • VEE / ISCA 等硬件相关会议

8.3 应用到新 workload(融合研究)

  • 把 AdaptX 控制面思路应用到 KV-cache 池(Loop X = 监控 cache hit rate,actuator = prefetch 策略)
  • 把 Mooncake KV pool 加到 CREST 的 MN 角色,做 disaggregated DB + LLM 共集群实验
  • OSDI / SIGMOD / VLDB

🌟 从复现到研究的关键一步:找一个 baseline 的失败模式,提一个新机制把它治掉。AdaptX 的整条思路就是这样发现的——“LOTUS 100ms 反应太慢” → “5ms 反应需要什么前置条件” → “需要 signal/actuator 抽象” → 控制面框架。


✅ 自我检验清单

  • 集群选型:能讲清 CloudLab / 自建 / 云三种方案的权衡
  • OFED 安装:在新机器上能 1 小时内装好 OFED 跑通 ibv_devinfo
  • perftest 数字:能解释为什么 ib_read_bw 比 ib_send_bw 略低
  • CREST 复现:能从空集群到看到 1.91× 加速,30 分钟内
  • 5 大坑全踩过:IOMMU / memcached / MR / TUN 劫持 / wrong dev_id
  • alt-extreme 反例:能跑出 0.87× regression 并解释为什么
  • 自己设计实验:能给出一个未跑过的 hot count + thread 组合,预测大致 ratio

📚 参考资料

实战环境

调优参考

  • NVIDIA Mellanox OFED Tuning Guide:NVIDIA 官方 —— PFC / DCQCN 调参权威
  • CloudLab Profile Documentation:docs.cloudlab.us —— small-lan / xl170 / d6515 等 profile 详细配置

行业讨论

  • Linux RDMA 邮件列表 —— driver 层问题诊断的最权威途径
  • Mellanox / NVIDIA Community Forum —— 常见问题集中地

框架文档

  • CloudLab Manual:docs.cloudlab.us
  • MLNX_OFED User Manual:NVIDIA 官方
  • DeepSpeed / FSDP 部署文档:训练侧实战延伸

🎓 模块结语

走完这八章,你已经把”分离式内存与新型互联”在 AI infra 中的位置摸清了:

  • 硬件层:RDMA 跨机柜 + CXL 机柜内,长期共存
  • 系统层:DM 事务 / KV-cache 池 / 训练 offload 三种范式
  • 设计权衡:延迟 / 容量 / 一致性的不可能三角始终在
  • 实战能力:能在 RDMA 集群上跑通至少一个生产级 demo

下一步往哪走?推荐三个方向:

  1. 研究:per-key admission、CXL+RDMA 协同、MVCC backup read 等 frontier
  2. 工业:把所学落地到推荐 / LLM serving / 数据库改造
  3. 横向拓展:回头看模块二 CUDA、模块三分布式训练,你会发现”如何在数据通路上协同”这个问题贯穿整个 AI infra

🌟 最后一句话:算力的 scaling law 已经写满了论文,数据通路的 scaling law 才刚开始写——这就是新型互联与远程内存系统这条赛道的价值