跳到主要内容
AURA 论文精讲

第2章:必备底座 —— atomic IOPS 物理墙、OCC、分离式架构

读 AURA 论文前的 30 分钟知识包:ConnectX 代际差异下 atomic IOPS 为什么有物理上限、RDMA OCC 三阶段标准实现、分离式内存 vs RDMA-attached storage 边界、CREST/FORD/Motor 共享的最小抽象(Pool / Hash Index / Cell-level CC)

RDMA atomic IOPS ConnectX OCC Disaggregated Memory CREST FORD Motor Hash Index Pool 论文精讲

第 1 章把 AURA 的主张和谱系定位讲清楚之后,紧接着的问题是:读到论文 §2 motivation 时,atomic IOPS 上限的”1 Mpps / 5 Mpps”数字、OCC validation 阶段的 read-set check、CREST 的 Pool / Hash Index 抽象,这些前置概念能不能不卡? 本章把读 AURA 必须先打通的 4 个底座一次性补齐——ConnectX 代际 atomic 行为差异、RDMA OCC 三阶段标准实现、分离式内存与 RDMA storage 边界、CREST/FORD/Motor 共享的最小抽象。读完直接进入第 3 章 motivation 重读不会卡。

📑 目录


1. 为什么需要这一章:读论文 §2 之前要懂的 4 件事

AURA 论文 §2 的 motivation chain 大致是这样:

§2.1:DM 事务里锁的获取依赖 MN 的 atomic(CAS / FAA),atomic IOPS 受 RNIC 内部串行化制约,上限是物理的§2.2:单纯客户端路由(把热点请求集中到一个 CN)不能减少 atomic 的 量,只能改变 分布§2.3:必须把”锁权威位置”作为一个可在线设计的物理参数对待。 §2.4:设计目标(5 条)。

这 4 段每一段都引用了一组”前提知识”:

§引用的前提如果不懂会怎样
§2.1RNIC 内 atomic 单元 + PCIe 串行看不懂为什么 ConnectX-3 / 6 数字差不了一个数量级
§2.2OCC validation 失败 → retry storm看不懂”路由不够”的物理原因
§2.3DM vs RDMA storage 边界容易把 AURA 当成 CXL 方案
§2.4CREST / FORD 的 Pool + Hash Index 抽象看不懂”在 CREST 上实现”具体改哪里

本章按上面 4 个前提分 4 节讲透。

🍎 学习节奏建议:每一节都有”☝️ 看到论文里出现这个词时,回到本节”的标签,先快速通读,做后续章节遇到术语时再回查。


2. RDMA atomic IOPS 物理墙:为什么不能水平扩

☝️ 看到论文里出现:“atomic IOPS 物理上限 / RNIC 串行化 / ConnectX 代际差异”时,回到本节

2.1 RNIC 内部 atomic 单元长什么样

RDMA 的 atomic 操作(CAS、FAA)和 READ/WRITE 不一样——它不是数据搬运,而是在 MN 的某段内存上做一次原子读改写。这需要 RNIC 上一个单 atomic 处理单元(Atomic Unit, AU)串行化处理所有 atomic 请求。

                              ┌──────── MN side ────────┐
                              │                          │
   CN ─ atomic_req ─► RNIC ─► AU (串行处理) ─► 内存原子写
                              │                          │
                              │  其他 atomic_req 排队等  │
                              └──────────────────────────┘

为什么必须串行?

  • PCIe 一致性:atomic 必须先把内存读到 RNIC 内部缓存、做修改、写回,整个过程要相对 MN CPU 的其他访问可线性化
  • 跨 QP 一致性:多个 CN 同时发 atomic 到同一段地址,必须有全局序
  • 硬件实现简化:单 AU 比多 AU + 锁简单,主流 RNIC 都这么做

🌟 结论atomic 的吞吐上限 = AU 处理速度 × 时间窗口,不随 QP 数、CN 数水平扩。

2.2 ConnectX 代际差异(实测)

下面是模块十五第 1 章 + AURA 论文用的标准实测数字(ib_atomic_bw -F -t 4 跑 64B CAS):

网卡上市年份atomic IOPS(实测)备注
ConnectX-32012~1 MppsAPT cluster 同款
ConnectX-3 Pro2014~1.2 MppsLOTUS 同款
ConnectX-4 / 52017~3–4 Mppsrdma-core 起点
ConnectX-6 Dx2020~5–10 MppsCloudLab c6525 同款
ConnectX-72023估算 ~10–15 Mpps未实测

🧠 关键洞察11 年从 1 Mpps 涨到 10 Mpps,远低于摩尔定律或 PCIe 带宽增长——因为 AU 单元的瓶颈不是带宽,是单点延迟(PCIe round trip + 内存 atomic latency),这两个在硬件上都没本质改进空间。

2.3 为什么 batch / coalescing / outstanding 救不了

第 1 章 §3 已经讲了反直觉点,本节补具体的物理原因:

  • batch 8 个 CAS 到一个 work request:硬件层仍按 8 次独立 atomic 处理,AU 不能并行执行 atomic
  • coalescing 写锁请求:只能减少 client 端发送次数,不减 MN 端原子处理次数(且会引入 serialization 在 client 侧)
  • 加 outstanding queue:队列堆深,延迟上升 → 端到端吞吐还是上限(Little’s Law:throughput = concurrency / latency,AU 是 throughput-bound)

🍎 直觉比喻:把 AU 想成银行总行只有一个 ATM 机的取款窗口

  • batch = 把 8 张卡装信封一起寄给银行 → 银行还是要一张一张刷
  • coalescing = 让客户排好队再来 → 银行 ATM 处理速度不变
  • outstanding queue = 让大家把卡都先交给银行排队 → 卡堆得越多,每张卡等的越久

🌟 结论atomic IOPS 是物理预算。AURA 论文 §2.1 的整个论证都站在这一条上。


3. RDMA OCC 三阶段标准实现

☝️ 看到论文里出现:“OCC validation / read-set / write-set / retry”时,回到本节

3.1 三阶段的标准时序

DM 事务系统(FaRM / FORD / Motor / CREST / AURA)全部基于 OCC,没有一家用 2PL(two-phase locking)。OCC 在 RDMA 上的标准三阶段是:

    时间 ─────────────────────────────────────────────────►

    [Read Phase] ─────► [Validation Phase] ──► [Commit Phase]
    │                   │                       │
    ├ RDMA READ 拉数据  ├ 重新 READ 读集校验   ├ CAS / WRITE 落盘
    ├ 记录到 read-set    │  版本号 / lock bit    ├ replicate
    ├ 在本地 buffer 改   ├ 失败 → abort, retry  └ unlock
    │  生成 write-set    │  成功 → 进 commit     │

三阶段每一阶段都对应 RDMA 操作:

阶段操作典型实现
Read一个 RDMA READ + 一个 read-set recordone-sided READ
Validation重读 read-set 验证版本/锁状态one-sided READ
Commit加锁 + 写值 + 解锁atomic CAS + RDMA WRITE + atomic FAA

3.2 Validation 失败 → retry storm 是怎么发生的

这是论文 §2.2 论证”路由不够”的核心:

   100 个事务都想写 same record

      ├─ Read phase 都拿到 version=5

      ├─ Validation phase 全部去 CAS(version=5 → version=6)

      ├─ 第 1 个成功,剩下 99 个 CAS 失败 → version_mismatch

      ├─ 99 个 abort + retry → 又是 100 个 CAS 请求

      └─ 形成 retry storm,**atomic IOPS 全用在 abort/retry 上**

🧠 关键洞察:retry storm 下,atomic 的有效吞吐 = AU 吞吐 / 平均 retry 次数。这是为什么”加 CN 反而更慢”的物理原因——加 CN 增加了发起 CAS 的客户端数,但 AU 上限不变。

3.3 OCC 在 AURA 里的位置

AURA 不改 OCC——三阶段还是这三个阶段,只是把 commit phase 的加锁那一步从”MN atomic CAS”换成”在 owner CN 上 OwnerLockTable 加锁”:

   原版 OCC 三阶段(FORD/Motor/CREST)           AURA 三阶段(local owner)
   ────────────────────────────────────         ───────────────────────────
   [Read]   RDMA READ                           [Read]   RDMA READ
   [Valid]  RDMA READ                           [Valid]  RDMA READ
   [Commit] MN atomic CAS  ──────► 物理墙       [Commit] OwnerLockTable 本地原子
            RDMA WRITE                                   RDMA WRITE
            MN atomic FAA                                 ───

🌟 结论AURA 的 atomic 不是消失了,是搬到了 CN 本地——CN 上原子操作走 CPU 指令(lock cmpxchg),不经过 RNIC AU,吞吐天花板从 5 Mpps 提升到 ~100 Mpps(4 CN × 单 CN 多核)。

📎 工程踩坑视角:CREST 上的具体改造在模块十五第 4 章 + 本模块第 8 章详讲。


4. 分离式内存边界:DM vs RDMA-attached storage vs CXL

☝️ 看到论文里出现:“Disaggregated Memory / DM 事务 / CXL Pool”时,回到本节

读 AURA 论文很容易把它当成”CXL 方案”或”RDMA storage 方案”。实际上 AURA 严格属于 **DM(Disaggregated Memory)**事务一支。三者边界:

维度DM(AURA / FORD / Motor)RDMA storage(NVMf / IB-SRP)CXL Pool(Pond)
内存语义字节寻址,远端 byte-addressable块语义(4KB / 64KB block)字节寻址,硬件一致性
访问原语RDMA verbs(READ / WRITE / CAS / FAA)NVMe-oF protocolload/store 指令
一致性软件维护(OCC / MVCC)块级(block-level)硬件维护
典型延迟2–5 μs50–200 μs200–400 ns
AURA 适用?✅ 这就是 AURA 的舞台❌ 块语义没 atomic❌ 硬件一致性消除热点

🌟 结论AURA 是为 RDMA + 字节寻址远端内存设计的事务系统。它的所有 motivation(atomic 物理墙、OCC retry storm)都基于”远端内存按 byte 寻址、原子操作走 RNIC AU”这个前提。

4.1 DM 事务的两层抽象

DM 事务系统的运行时分两层:

   ┌─ CN (Compute Node) ───────────────────────────────┐
   │  - 应用 + 事务逻辑                                 │
   │  - 协程调度 / 工作线程                             │
   │  - OCC 三阶段实现                                  │
   │  - 本地 cache / write buffer                       │
   └─────────────────┬──────────────────────────────────┘
                     │ RDMA verbs(双向 + 单向)
   ┌─────────────────▼──────────────────────────────────┐
   │  MN (Memory Node)                                  │
   │  - 内存池(Pool)                                  │
   │  - Hash Index / Btree(FORD/Motor 数据结构)       │
   │  - 不跑应用逻辑(除了 atomic 的 AU 处理)          │
   └────────────────────────────────────────────────────┘

🧠 关键洞察MN 不跑应用逻辑。所有”算”都在 CN 上,MN 只是被 RDMA 操纵的内存。这是 DM 和”远程 KV 服务”的本质区别。

📎 工程踩坑视角:CREST 的 MN motor_mempool 实现就是这个——它只 listen RDMA 连接 + 注册 MR,几乎没有 CPU 逻辑,CN 端完全通过 RDMA 操纵远端内存做事务。


5. CREST / FORD / Motor 共享的最小抽象

☝️ 看到论文里出现:“Pool / PoolHashIndex / Cell-level CC / masked-CAS”时,回到本节

AURA 的实现是在 CREST 上做的,CREST 又继承了 FORD/Motor 的部分抽象。这一节把”读 AURA 实现章必须先认识的 5 个抽象”列清楚——后面 §5 / §8 章会反复用。

5.1 Pool:MN 的内存池基本单位

// 简化版(来自 src/mempool/Pool.h)
class Pool {
    void* base_;          // 注册 MR 的起始地址
    size_t size_;         // MR 总大小
    PoolHashIndex* idx_;  // 一个或多个 hash index 指针
    // ... allocator state
};

🌟 结论:Pool 是 MN 上一段已经注册 MR 的连续内存,CN 通过 rkey + offset 用 RDMA 操纵。

5.2 PoolHashIndex:远端 hash 表

   bucket[0]:  ┌──────────┬──────────┬──────────┐
               │ slot[0]  │ slot[1]  │ slot[2]  │
               │ key/val  │ key/val  │ key/val  │
               │ version  │ version  │ version  │
               │ lock_bit │ lock_bit │ lock_bit │
               └──────────┴──────────┴──────────┘
   bucket[1]:  ┌──────────┬──────────┬──────────┐
               │ ...                              │

每个 slot 是一个 cache-line 对齐的记录,包含:

  • key + value
  • version(OCC 用)
  • lock bit / lock holder id(cell-level CC 用)

🧠 关键洞察lock bit 在 slot 里、不在单独的 lock table 里——这是 FORD 提出的 “in-data lock”。CAS 时 mask 掉 version + value,只看 lock bit,称为 masked-CAS。AURA 的 fallback 路径走的就是这个 masked-CAS(论文 §3.x FallbackLock)。

5.3 Cell-level CC:CREST 的并发控制粒度

CREST 把锁粒度从 row 拆到 cell(单个字段)——一行有 N 个字段就有 N 个 lock bit。

   record:  ┌─────────┬─────────┬─────────┬─────────┐
            │ field 0 │ field 1 │ field 2 │ field 3 │
            │ lock=1  │ lock=0  │ lock=0  │ lock=1  │
            └─────────┴─────────┴─────────┴─────────┘

🌟 结论cell-level CC 显著降低 false conflict。AURA 不改这一层——它在 cell-level CC 之上抽象出 cohort(key_group 的集合),cohort 与 cell 是不同维度的抽象。

5.4 masked-CAS:在 64B cache line 上同时改锁 + 版本

   64B cache line layout:
   ┌──────────┬─────────────┬──────────┬─────────┐
   │ lock_bit │ version (4B)│ payload  │ padding │
   │  (1B)    │             │ (54B)    │ (5B)    │
   └──────────┴─────────────┴──────────┴─────────┘

   CAS old: (lock=0, version=5, payload=X)
   CAS new: (lock=1, version=6, payload=Y)
   compare_mask: 0xFFFFFFFFFFFFFFFF (整条 line)

📎 工程踩坑视角:CREST 的 RDMA masked-CAS 必须落在 64B cache line 内,跨 line 的 CAS 不是原子的。这是 §5 实现章会反复出现的约束。

5.5 OwnerLockTable:AURA 在 CN 端加的新抽象

// 简化版(来自 src/transaction/aura/OwnerLockTable.h)
class OwnerLockTable {
    std::unordered_map<KeyGroupId, LockEntry> entries_;
    // 每个 entry: lock_holder, version, txn_queue
    // 操作: TryAcquire / Release / Hand-off
};

🌟 结论OwnerLockTable 是 AURA 在 CN 上加的本地锁服务——key 是 cohort 内的 key_group,value 是锁状态。本地 lock_cmpxchg 替换了 MN atomic CAS。

   原来:  CN ──RDMA atomic CAS──► MN AU         (吞吐受限)
   AURA:  CN ──本地 lock_cmpxchg──► OwnerLockTable(本机 CPU)

第 4 章 / 第 5 章会展开 OwnerLockTable 的 cohort 安装、迁移协议、跨 CN OwnerRpc 慢路径。


6. 把这些底座叠在一起:一张事务读路径速查图

把本章 4 节叠成 AURA 上一个 NewOrder 事务从读取到提交的完整路径图(精简版,详细版在第 4 / 7 章):

   ┌─── CN ──────────────────────────────────────────────┐
   │                                                       │
   │   1. 应用决定要读 stock(w_id=2, i_id=42)              │
   │       │                                               │
   │   2. 查 OwnerLockTable: cohort owner = self?          │
   │       │                                               │
   │       ├─ 是 → 本地 TryAcquire                         │
   │       │      └─ 成功 → 拿到锁                         │
   │       │                                               │
   │       └─ 否 → OwnerRpc 慢路径 → 远端 CN                │
   │              └─ 远端 OwnerLockTable.TryAcquire        │
   │                                                       │
   │   3. RDMA READ 拉 stock record                        │
   │       │                                               │
   │   4. 在本地 buffer 改值(计算 new stock)             │
   │       │                                               │
   │   5. Validation: 重读,版本一致?锁仍在?             │
   │       │                                               │
   │   6. Commit:                                          │
   │       ├─ owner local: 本地版本号 +1 + RDMA WRITE      │
   │       └─ fallback: masked-CAS on MN slot              │
   │                                                       │
   │   7. Release lock(本地或 RPC)                        │
   │                                                       │
   └───────────────────────────────────────────────────────┘

🧠 关键洞察:步骤 2 是 AURA 引入的新分支——根据 OwnerMap manifest 决定走本地 fast path 还是 RPC slow path。所有 §3 的算法(cohort 学习、ownership planning、affinity routing)都是为了让”是 → 本地 TryAcquire”这条分支命中率最大化

✅ 自我检验清单

  • atomic 物理墙:能解释为什么 ConnectX-3 与 ConnectX-6 atomic IOPS 只差 ~5 倍(AU 单点延迟、PCIe 串行)
  • batch 反直觉:能用”银行 ATM”比喻解释为什么 batch / coalescing 不能压住 atomic 上限
  • OCC 三阶段:能徒手画 Read / Validation / Commit 三阶段 + 每阶段用什么 RDMA 操作
  • retry storm:能解释 OCC validation 失败为什么会形成 retry storm
  • DM 边界:能区分 DM / RDMA storage / CXL Pool 三者的访问语义
  • Pool / PoolHashIndex / Cell-level CC:能说出 CREST 上这三层各自的职责
  • masked-CAS:能解释为什么 masked-CAS 必须落在 64B cache line 内
  • OwnerLockTable:能说出 AURA 把原 MN atomic 替换成什么(本地 lock_cmpxchg)

第 3 章预告

第 3 章按论文 §2 的 motivation chain 顺序,逐段重读:

  • §2.1 锁瓶颈 → 本章 §2 atomic 物理墙的论证版本
  • §2.2 为什么单纯路由不够 → retry storm + 5 种 DM 锁热点对照
  • §2.3 从数据物理设计到锁所有权物理设计 → MorphoSys / Lion 类比 + AURA 的代差
  • §2.4 设计目标 5 条 → 每条对应后续哪个章节

读完第 3 章你能徒手把 §2 motivation 三段论复述给同行听。


📚 参考资料

关键论文 / 文档

  • Mellanox ConnectX 系列 datasheet —— atomic 单元 + AU 描述(厂商 PDF)
  • RDMA Aware Programming User Manual (Mellanox, 2020) —— OCC 三阶段标准实现参考
  • FORD (Zhang et al., FAST’22) —— in-data lock + masked-CAS 的奠基论文:USENIX 链接
  • Motor (Wu et al., OSDI’24) —— MVCC + 一致版本表:USENIX 链接
  • Pond (Li et al., ASPLOS’23) —— Microsoft 云端 CXL 1.1 实测(用作 DM vs CXL 边界对照)

测量工具

  • perftest 套件ib_atomic_bw / ib_read_bw / ib_write_bw —— Mellanox OFED 自带
  • ib_atomic_bw 标准跑法ib_atomic_bw -F -t 4 -s 64 --report_gbits —— AURA 论文 §2.1 实测脚本

模块内交叉引用