土法炼钢兴趣小组的算法知识备份

【数据库研究前沿】共享内存数据库复兴:RDMA/CXL 下的分布式事务

文章导航

分类入口
database
标签入口
#rdma#cxl#farm#nam-db#sundial#distributed-transaction#shared-memory

目录

“共享内存数据库”一度被认为是历史的遗物。经典的 shared-memory 多处理器系统(SGI Origin、IBM z 系列)因为扩展性受限,在 2000 年代几乎被 shared-nothing 架构全面取代。Google、Facebook、Amazon 的在线系统清一色走”每台机器独立内存 + 网络 RPC + 分片数据”的路线,教科书里也把 shared-nothing 写成默认选项。

但近十年有两股力量在悄悄把这个结论往回掰:RDMA(Remote Direct Memory Access) 让跨机访问远端内存的延迟降到几微秒、单边操作能绕过远端 CPU;CXL(Compute Express Link) 进一步把多台机器的内存挂到同一个一致性域下,提供硬件级 cache coherence。在这两种硬件之下,“一个进程能直接 load/store 另一台机器的内存”,从比喻变成现实。

微软研究院的 FaRM(SOSP 2015、NSDI 2014)、FaRMv2(SOSP 2019),苏黎世联邦理工的 NAM-DB(VLDB 2017),MIT 的 Sundial(OSDI 2018)是这条线的代表:它们都从”RDMA 单边读”或”硬件支持的跨机一致性”出发,重新设计事务协议。这不是把旧 shared-memory DBMS 搬回来,而是一种 hybrid 架构:既有 shared-nothing 的分片与独立故障域,又有 shared-memory 的低延迟共享访问路径

本文上半部分梳理这四个系统的核心机制、RDMA 单边操作的 trade-off,以及 CXL 对共享内存模型的改变;下半部分讨论什么情况下 RDMA 集群真的比经典 shared-nothing 值得,以及调优的难点。

版本说明 本文引用 FaRM(SOSP 2015、NSDI 2014)、FaRMv2(SOSP 2019)、NAM-DB(VLDB 2017)、Sundial(OSDI 2018)等论文,以及 CXL 3.0 spec(2022)、Intel / Samsung 等厂商在 2023–2024 年公开的 CXL 内存池产品资料。


一、RDMA 单边操作:新硬件、新边界

1.1 RDMA 提供了什么

RDMA 最常用的 verb 分成两类:

对数据库来说,one-sided 是颠覆性的:跨机访问数据时,远端 CPU 不被唤醒。这意味着:

  1. 远端没有 CPU 开销,不需要 context switch;
  2. 网络延迟可以低到 1–3 µs(InfiniBand EDR/HDR),比传统 TCP 低一到两个数量级;
  3. 吞吐可以到几百万 ops/s 每核心。

典型延迟数字(常见 InfiniBand 设备,数据随硬件代际变化):

操作 典型延迟
本地内存 load ~100 ns
本地 NVMe SSD 随机读 ~100 µs
RDMA one-sided READ(同机架) 1–3 µs
RDMA two-sided SEND/RECV 2–5 µs
传统 TCP RPC(同机架) 30–100 µs

三个量级:内存 / RDMA / TCP,在数据库设计里意味着”远端内存”从”比本地慢 1000ד变成”比本地慢 10–30ד。

1.2 RDMA 单边操作的三种典型用法

在进入具体系统之前,先明确 one-sided 在数据库里最常见的三种模式:

  1. 远端读取数据页 / 元数据:发起端已知目标地址,直接 READ 过来。常用于读副本拉页、远端索引节点查询。
  2. 远端 CAS 抢锁 / 版本号:用 atomic compare-and-swap 在远端内存上实现分布式锁或乐观更新。
  3. 写日志到远端副本:主库把 WAL record 用 WRITE 直接塞进备库预分配的日志 buffer,备库 CPU 几乎不参与,只在 commit 时读一下尾指针。

这三种用法共同点:发起端完全掌控协议,远端只是一块被动的内存。这让远端 CPU 可以专注做其他工作,整机效率大幅提升。代价是发起端的代码复杂度飙升——它需要自己管理远端内存布局、处理可能的撕裂、重试与超时。

后面 FaRM、NAM-DB、Sundial 所做的协议改造,基本都围绕这三种用法在不同事务阶段的组合展开。

1.3 单边操作的代价

one-sided 看起来完美,但有三个重要约束:

  1. 没有远端计算。发起端拿到的是裸字节,任何语义解码、索引查找、锁检查都得发起端自己做。
  2. 没有原子性跨多块。RDMA 提供 compare-and-swap 和 fetch-and-add,但只对单个 8 字节有效。跨多块的原子更新要软件实现。
  3. 没有 cache coherence。发起端不知道远端 CPU 是否正在修改某块内存。如果远端 CPU 也在写、发起端也在读,缺乏 cache coherence 的话,可能读到撕裂值。

这些约束决定了”基于 RDMA 的数据库”不能简单”把所有数据放远端、所有操作走 one-sided”。它必须在协议层面设计如何绕开这些约束。

1.4 RDMA 对协议的影响

有 RDMA 之后,几个经典设计点会被重新考虑:

接下来几节看这些原则在 FaRM、NAM-DB、Sundial 里怎么具体落地。


二、FaRM:基于 RDMA 的分布式内存事务

2.1 设计目标

Dragojević 等人在 NSDI 2014 的 “FaRM: Fast Remote Memory” 与 SOSP 2015 的 “No Compromises: Distributed Transactions with Consistency, Availability, and Performance” 提出 FaRM:

FaRM 不仅是一次 “用 RDMA 加速事务” 的实验,更是一次系统性地回答 “如果远端内存访问只比本地慢 10×,事务协议怎么设计最省时” 的尝试。

2.2 事务协议

FaRM 的事务协议是乐观并发控制(OCC)的变体,大致三阶段:

  1. 读阶段:用 RDMA one-sided READ 从各数据分片拉读集。每次读记录 version。
  2. 验证阶段(validate):一阶段 lock + 重读 version 比对。对写集用 CAS 获取 lock;读集只做 version 对比。
  3. 提交阶段(commit):写入新值,发送 commit 日志到多个副本;拿到多数确认后释放锁。

关键 RDMA 优化:

这让一个跨 3 台机器的小事务端到端延迟可以压到 10–20 µs。

2.3 故障恢复

FaRM 把副本放在”主 + 多个 backup”上,主挂了由 backup 接管。故障检测基于心跳与 lease;接管过程要重建内存状态(从其他副本同步)。内存系统的挑战:机器重启后内存为空,必须从其他节点拉数据。FaRM 的答案是多副本 + 快速并行恢复。

2.4 FaRMv2:垂直分区与 opacity

SOSP 2019 的 “FaRMv2” 在 FaRM 基础上做了几项重要改动:

  1. opacity(Transactional Opacity):保证即使 abort 的事务也只读到一致快照,避免”读到不一致中间状态导致业务逻辑崩溃”。这是 Transactional Memory 里的术语,数据库事务里常叫 “consistent reads”。
  2. snapshot isolation 读:在 OCC 上实现快照隔离读,读不加锁、不验证,代价是读可能稍旧但 abort 率低。
  3. 更大内存 / 垂直分区:把数据按”热 / 冷”或”读 / 写”做垂直分区,减少每次事务要跨多少机器。

FaRMv2 的论文给出一个有意思的数字:在 TPC-C 类工作负载下,FaRMv2 把吞吐推到了百万 tpmC 每核心的量级(具体数字见论文表格)。

2.5 FaRM 的启示

FaRM 系列系统的贡献不是”发明了新事务协议”——它的 OCC + 2PC 本质上是经典的——而是系统级地证明了:在 RDMA 假设下,精心设计的 OCC + 多副本日志复制可以同时拿到强一致、高可用、低延迟,“CAP 只能选二”的口号被狠狠打了折。


三、NAM-DB:共享内存抽象 + 无中心 timestamp

3.1 NAM 架构

Zamanian 等人在 VLDB 2017 的 “The End of a Myth: Distributed Transactions Can Scale” 提出 NAM(Network-Attached Memory)架构:

+-------------+    +-------------+    +-------------+
| compute 1   |    | compute 2   |    | compute 3   |   只有计算
+------+------+    +------+------+    +------+------+
       |                  |                  |
       +--- RDMA one-sided --+--- RDMA one-sided --+
                            |
            +---------------+---------------+
            |   memory servers (shared)     |   只存数据,不跑业务逻辑
            +-------------------------------+

关键设计:

这是 “shared-memory” 在分布式世界的回归,但不是把所有机器塞进一个硬件一致性域——每个 memory server 还是独立故障域,coherence 由软件维护。

3.2 无中心 timestamp

NAM-DB 处理的一个关键难题是:分布式 timestamp 分配。经典方案有 TSO 服务(如 TiDB 的 PD,见《Percolator》)或 TrueTime(Spanner)。TSO 集中分配,在每秒千万 tps 下是瓶颈。

NAM-DB 的做法:timestamp 也是共享内存中的一个 counter。所有 compute 节点通过 RDMA fetch-and-add 在 memory server 上原子递增这个 counter。这比集中 TSO 服务少一跳 RPC,延迟约为一次 one-sided atomic(2–3 µs)。

缺点:fetch-and-add 对单个 8 字节 counter 的吞吐有极限(每秒几百万)。NAM-DB 的解决是分段或批量获取。

3.3 事务协议与 snapshot 隔离

NAM-DB 使用多版本并发控制:每条记录带多个版本,每个版本标注 begin_ts / end_ts。读一条记录时带上事务 read_ts,从版本链中挑”对当前事务可见”的那个版本。

写入:写到新版本,不覆盖老版本;commit 时写 end_ts 到旧版本 + begin_ts 到新版本。

这个协议本身是经典 MVCC(Snapshot Isolation),RDMA 的作用是把每一步操作的延迟压低,使得整个事务在微秒级完成。

3.4 NAM-DB 的意义

NAM-DB 论文的标题 “Distributed Transactions Can Scale” 针对的是流传很广的论断 “分布式事务天生不能扩展” (来自早期 Google 关于 Spanner 之前的经验文章)。NAM-DB 证明:在 RDMA 网络下,分布式事务可以做到每秒数百万的吞吐,原来的论断受限于”以太网 + TCP”这个隐含前提。


四、Sundial:逻辑租约替代锁等待

4.1 设计起点

Yu 等人在 OSDI 2018 提出 Sundial。问题背景:OCC 在高冲突下 abort 率高;2PL 在跨机场景下锁等待长。能不能在读阶段就知道读集的未来”可用时间段”,从而避免 abort?

Sundial 的答案是:每条记录带一个逻辑租约(lease)。租约是一个时间戳区间 [wts, rts]:

读一条记录,把该事务的 commit ts 往 [wts, rts] 内挤;如果挤不进去,就要延长 rts(租约续借)。写入时要保证 rts 没有超过新写入事务的 ts。

4.2 事务流程

  1. 事务执行中收集读集、写集;读时记录 wts/rts。
  2. 尝试给事务选一个 commit ts:必须满足所有读的 wts ≤ commit_ts ≤ rts,所有写的 rts < commit_ts。
  3. 如果某条读记录 rts < commit_ts,尝试”续借”:联系远端、把 rts 推到 commit_ts。如果远端同意(没有更大的事务占用),成功;否则 abort。
  4. commit 时写新版本 + 更新 wts。

4.3 和 OCC / 2PL 的关系

Sundial 可以看作OCC 的改进版:在 OCC 的 validate 阶段,不是简单”读是否被改过”,而是”这条读能不能延长它的有效期”。这让一些原本会 abort 的事务可以 commit,减少 wasted work。

4.4 Sundial 的 RDMA 用法

Sundial 论文本身不是专门讲 RDMA 的,但实现上大量使用 RDMA one-sided 读写和 CAS,把租约更新的 RTT 压到微秒级。这是典型的”协议改进 + 硬件红利”结合:租约协议减少 abort,RDMA 减少每步延迟。

4.5 Sundial 与 TSO 的关系

Sundial 的”逻辑租约”某种意义上可以看作去中心化的 TSO:每条记录携带自己的有效时间窗,事务在 commit 时”拼凑”一个合法的 commit_ts。这和 Percolator 的集中 TSO 形成鲜明对比:

三者适用的工作负载不同:Percolator 在跨 region 大规模 OLTP 下成熟(TiDB 即是代表);Sundial 在单机房 RDMA 高冲突 OLTP 下优势明显;NAM-DB 把 timestamp 分配延迟压到微秒以下,适合 in-memory 高吞吐场景。


五、CXL:真正的硬件共享内存回来了

5.1 CXL 是什么

CXL(Compute Express Link)是 PCIe 之上的一个协议栈,由 Intel 主导、CXL Consortium 发布。关键是它包含三个子协议:

CXL 3.0(2022)进一步支持跨主机的内存池:多台主机连到同一个 CXL switch,挂载共享的内存池,所有主机可以直接 load/store 访问那块内存,且硬件提供 cache coherence。

这是过去二十年 shared-nothing 盛行以来,第一次有主流硬件提供跨机器的硬件一致性域

5.2 CXL 对数据库架构的潜在影响

想象一个 CXL pool 配合 4 台数据库 compute 的部署:

这种架构下,很多 RDMA 数据库做的事情(one-sided READ、CAS、版本比较)可以退化成普通内存指令。数据库又可以回到”shared memory + 并发编程”的古典姿势——只是现在每台物理机的 CPU 跨板共享内存。

5.3 现实中的限制

截至目前(2024 年公开资料):

所以 CXL 的前景是“在机柜内提供准本地的共享内存”,不是跨 rack、跨 AZ 的 shared memory。它更像是 NUMA 的扩展,而不是”消灭网络”。

5.4 CXL 下的协议再思考

如果 CXL 成立,前面几个系统的一些设计可以简化:

但 CXL 不会取代 RDMA。CXL 受限于物理距离(机柜内),跨机柜、跨 AZ 仍然要靠 RDMA 或以太网。未来几年最可能的形态是“机柜内 CXL + 机柜间 RDMA + AZ 间 TCP” 的三层网络层级,每层对应不同的延迟预算和协议设计。

5.5 CXL 内存分层的实际部署形态

CXL 在数据库里最现实的几种用法,从保守到激进:

  1. 单机内存扩展:把 CXL 内存当本地 DRAM 使用,用来扩大 buffer pool / 排序临时区。延迟比本地 DRAM 慢 2–3 倍,但容量可以几 TB,成本低于等量 DRAM。
  2. 跨 NUMA 但单主机:一台主机多 socket,用 CXL 把远端 socket 的内存抽象成统一地址空间,改善 NUMA 命中。
  3. 机柜内多主机内存池:几台主机共享一个 CXL pool 里的冷数据区或共享锁表。
  4. 全共享 buffer pool:几台 compute 共用一块 CXL 内存作为 buffer pool,做读扩展。
  5. 共享事务状态:进一步把 MVCC 版本链 / 锁表 / timestamp counter 放到 CXL 共享内存,所有 compute 直接 load/store 访问。

工业界目前的主流尝试停在第 1 和第 2 层,研究方向逐步向 3、4 层探索;第 5 层还偏早期,需要数据库引擎深度改动并且硬件故障模型成熟。

5.6 一致性与故障隔离

CXL 硬件提供 cache coherence,但这只解决 “读到旧值” 问题,不解决 “数据被其他主机写坏”。当一块内存被多 host 写入,数据库仍要在软件层做并发控制:

CXL 让”跨主机 bug 影响范围”从”单机 crash” 扩大到”共享 pool 关联的所有主机”,运维上要重新设计隔离策略——例如把不同租户绑到不同 pool、把关键锁结构冗余化等。

5.7 CXL 与 RDMA 的分工前景

把 CXL 和 RDMA 放在同一张延迟 / 距离图上看:

              延迟
              ^
  TCP         |   ~ 30-100 µs        跨 AZ / region
              |
  RDMA        |   ~ 1-5 µs          跨机柜 / 同 rack
              |
  CXL         |   ~ 200-500 ns      机柜内 / 同 PCIe domain
              |
  local DRAM  |   ~ 100 ns          单机
              |------------------->  距离

未来 5 年数据库可能演进出”每一层都用最合适的技术”的部署形态:

RDMA 不会消失,CXL 也不会独占,它们是不同距离段的工具。能把四种路径组合起来的系统,才有可能在”单机性能 + 跨机一致性 + 跨 region 可用性”三者间同时做到很好。


六、选型:RDMA 集群 vs 经典 shared-nothing

6.1 什么时候 RDMA 值得

RDMA 集群的收益主要在三种场景:

  1. 跨机小事务密集:每秒百万级小事务,单事务跨几条记录。TCP RPC 的 30–100 µs 成为瓶颈,RDMA 能把延迟压下去。
  2. 分布式 OLAP 或 shuffle:大数据计算里 shuffle 阶段的数据搬运,RDMA 能显著提升吞吐。
  3. 主备复制链路:主写备以 RDMA write 落到备的内存日志区,commit 延迟可以压到几微秒。

相对的,如果你的业务:

那经典 shared-nothing + TCP 完全够用,不需要上 RDMA。RDMA 的复杂度、硬件成本、运维负担在小规模下是纯亏损

6.2 RDMA 集群的硬约束

不是有了 RDMA 网卡就能用:

  1. 同网段、低跳数:RDMA 对跨交换机跳数敏感,通常部署在同一 pod / 机架组内。
  2. RoCE vs InfiniBand:RoCE 走 Ethernet,兼容性好但对 switch 的 PFC(Priority Flow Control)配置要求高;InfiniBand 专有网络,性能稳定但成本高。
  3. 内存管理复杂:RDMA memory region 需要显式注册(memory pinning),大量动态分配会拖慢性能。
  4. 应用层编程难度高:verbs API 远比 socket 复杂,调试工具链也相对单薄。

在工程上 RDMA 数据库的常见教训:debug 一个诡异性能问题,最后发现是网卡固件版本、交换机 PFC 配置、或者 NUMA 亲和性问题。这些问题在普通 TCP 下很少遇到。

6.3 CXL 的选型建议

现阶段(2024 末)对 CXL 的务实建议:

6.4 一个可工作的决策流程

在团队里推动”要不要上 RDMA” 时,建议按以下流程走:

  1. 先做 TCP 基线 profiling:看当前事务延迟的分布,99% 时间花在哪——如果大部分时间在磁盘 IO、锁等待、应用逻辑,那 RDMA 没用武之地。
  2. 估算事务跨机率:如果分片设计让 95% 事务落在单机,跨机事务总体就不是瓶颈。
  3. 评估硬件预算:RDMA 网卡 + 低延迟交换机的单节点成本比普通以太网高 2–5 倍。
  4. 评估团队工程能力:团队里没有熟悉 verbs API、能读懂 ibv_poll_cq 性能问题的人,先别上。
  5. 做 PoC:选 1–2 个核心事务类型,用 RDMA 改写关键路径,测延迟与吞吐。
  6. 看收益是否翻倍:如果收益小于 2×,硬件 + 运维的复杂度溢价不值得。

这个流程不华丽,但能把大部分”跟风上 RDMA” 的需求筛掉。真正从 RDMA 中显著受益的业务,普遍是金融交易所、广告实时竞价、大规模 kv-cache 这类对微秒级延迟有商业价值的场景。


七、调优难点

7.1 NIC 与队列调度

RDMA 性能对 NIC 配置极其敏感。常见调优点:

这些配置在不同 NIC 型号(Mellanox ConnectX-5 / 6 / 7)上最优值都不同,需要针对硬件做实测。

7.2 CPU 亲和性与 NUMA

RDMA 的 CPU 开销主要在 poll completion、处理 context。调优要点:

7.3 一致性与并发控制的坑

7.4 观测与调试

7.5 一个常见误区:RDMA 不自动提升吞吐

团队第一次用 RDMA,经常拿”RDMA 延迟 2 µs” 去推算”吞吐应该是 TCP 的 10 倍”,结果实测只快 1.5–2 倍,然后怀疑是不是硬件坏了。实际上:

所以使用 RDMA 前要明确目标:是降延迟,还是提吞吐? 两者优化手段不一样,不能简单期望”都能得到”。

7.6 冷热路径的不同选择

一个实用的设计原则:不要用 RDMA 替换所有路径。更好的做法是:

这样既享受 RDMA 的红利,又避免把整个系统都绑死在 RDMA 语义上,系统跨机房扩展时也容易降级运行(跨 region 没有 RDMA 时,冷路径继续工作,热路径优雅回退)。


八、小结与展望

RDMA 与 CXL 让”共享内存”这个被判死刑的架构范式以新形态回来:

但这两个方向不是要取代 shared-nothing,而是在 shared-nothing 的基础上,给”跨机延迟敏感”的层注入新能力。一个现实的大型数据库架构,未来可能同时具备:

每一层用合适的协议与硬件,不要求”一种协议通吃所有”。这是接下来几年高性能数据库架构的大致方向。

论文里”百万 tps 每核心”的数字很漂亮,但记住:那是在理想硬件、小规模冲突、单工作负载下测出来的。真实系统里,硬件故障、混合工作负载、运维复杂度会把这些数字打折。在决定是否把 RDMA / CXL 引入生产前,先用第六节的简单判据看你是否真正处在”微秒级延迟有商业价值”的区间。

对研究者与架构师,一个值得长期关注的问题是:随着 RDMA 与 CXL 的成熟,OCC、MVCC、2PL 这些经典协议是否有新的最优形态?FaRMv2、Sundial 已经给出了一些答案,但远不是终点。下一代”shared-memory native” 的事务协议可能会在 2025–2030 年之间逐渐成型,这是数据库领域少有的、底层硬件真的会推动上层协议重新设计的时刻与机遇。对正在选择研究方向的博士生和架构师来说,这是一个难得的机会窗口,值得持续关注与投入。它也提醒我们:架构和协议永远与硬件绑定,脱离硬件谈”最优协议”没有意义。


参考文献

  1. Dragojević A., et al. FaRM: Fast Remote Memory. NSDI 2014. https://www.usenix.org/conference/nsdi14/technical-sessions/dragojevic
  2. Dragojević A., et al. No Compromises: Distributed Transactions with Consistency, Availability, and Performance. SOSP 2015.
  3. Shamis A., et al. FaRMv2: Fast General Distributed Transactions with Opacity. SOSP 2019.
  4. Zamanian E., et al. The End of a Myth: Distributed Transactions Can Scale. VLDB 2017. https://www.vldb.org/pvldb/vol10/p685-zamanian.pdf
  5. Yu X., Xia Y., Pavlo A., Sanchez D., Rudolph L., Devadas S. Sundial: Harmonizing Concurrency Control and Caching in a Distributed OLTP Database Management System. VLDB 2018 / OSDI 2018.
  6. Compute Express Link Consortium. CXL 3.0 Specification. 2022. https://www.computeexpresslink.org/
  7. Kalia A., Kaminsky M., Andersen D. G. Design Guidelines for High Performance RDMA Systems. USENIX ATC 2016.

上一篇【数据库研究前沿】Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式

下一篇【数据库研究前沿】CXL 与数据库的新内存层级

同主题继续阅读

把当前热点继续串成多页阅读,而不是停在单篇消费。


By .