“共享内存数据库”一度被认为是历史的遗物。经典的 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 分成两类:
- two-sided(send/recv):语义类似 TCP,发送端 post send,接收端 post recv。两边 CPU 都要参与。
- one-sided(read/write/atomic):发起端直接读写远端内存地址,远端 NIC(Network Interface Card)在不打扰远端 CPU 的情况下完成 DMA。
对数据库来说,one-sided 是颠覆性的:跨机访问数据时,远端 CPU 不被唤醒。这意味着:
- 远端没有 CPU 开销,不需要 context switch;
- 网络延迟可以低到 1–3 µs(InfiniBand EDR/HDR),比传统 TCP 低一到两个数量级;
- 吞吐可以到几百万 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 在数据库里最常见的三种模式:
- 远端读取数据页 / 元数据:发起端已知目标地址,直接 READ 过来。常用于读副本拉页、远端索引节点查询。
- 远端 CAS 抢锁 / 版本号:用 atomic compare-and-swap 在远端内存上实现分布式锁或乐观更新。
- 写日志到远端副本:主库把 WAL record 用 WRITE 直接塞进备库预分配的日志 buffer,备库 CPU 几乎不参与,只在 commit 时读一下尾指针。
这三种用法共同点:发起端完全掌控协议,远端只是一块被动的内存。这让远端 CPU 可以专注做其他工作,整机效率大幅提升。代价是发起端的代码复杂度飙升——它需要自己管理远端内存布局、处理可能的撕裂、重试与超时。
后面 FaRM、NAM-DB、Sundial 所做的协议改造,基本都围绕这三种用法在不同事务阶段的组合展开。
1.3 单边操作的代价
one-sided 看起来完美,但有三个重要约束:
- 没有远端计算。发起端拿到的是裸字节,任何语义解码、索引查找、锁检查都得发起端自己做。
- 没有原子性跨多块。RDMA 提供 compare-and-swap 和 fetch-and-add,但只对单个 8 字节有效。跨多块的原子更新要软件实现。
- 没有 cache coherence。发起端不知道远端 CPU 是否正在修改某块内存。如果远端 CPU 也在写、发起端也在读,缺乏 cache coherence 的话,可能读到撕裂值。
这些约束决定了”基于 RDMA 的数据库”不能简单”把所有数据放远端、所有操作走 one-sided”。它必须在协议层面设计如何绕开这些约束。
1.4 RDMA 对协议的影响
有 RDMA 之后,几个经典设计点会被重新考虑:
- 两阶段提交(2PC):prepare / commit 的 RTT 从毫秒级降到微秒级,相对其他开销变得可以接受,协议本身不再是瓶颈。
- 锁管理器:传统锁表要么集中(单点瓶颈)要么分布(高 RTT)。RDMA 下可以用 one-sided CAS 在远端内存上做乐观锁,几乎没有单点瓶颈。
- 日志复制:主库可以 one-sided write 把日志直接放进备库内存,备库 CPU 只在 commit 时 poll 一下。
- 缓存一致性:共享 buffer pool 跨机访问变得现实。
接下来几节看这些原则在 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:
- 所有数据常驻内存;
- 跨机访问全部走 RDMA(一开始大量用 one-sided READ);
- 提供可串行化的分布式事务;
- 目标:单事务微秒级延迟,百万级事务每秒吞吐。
FaRM 不仅是一次 “用 RDMA 加速事务” 的实验,更是一次系统性地回答 “如果远端内存访问只比本地慢 10×,事务协议怎么设计最省时” 的尝试。
2.2 事务协议
FaRM 的事务协议是乐观并发控制(OCC)的变体,大致三阶段:
- 读阶段:用 RDMA one-sided READ 从各数据分片拉读集。每次读记录 version。
- 验证阶段(validate):一阶段 lock + 重读 version 比对。对写集用 CAS 获取 lock;读集只做 version 对比。
- 提交阶段(commit):写入新值,发送 commit 日志到多个副本;拿到多数确认后释放锁。
关键 RDMA 优化:
- 验证阶段的 lock 用远端内存上的 per-object lock word,通过 one-sided CAS 直接抢;
- commit 日志走 one-sided WRITE 放进备库日志区,备库 CPU 只在必要时被唤醒;
- 读阶段不需要远端 CPU 参与,直接 RDMA READ。
这让一个跨 3 台机器的小事务端到端延迟可以压到 10–20 µs。
2.3 故障恢复
FaRM 把副本放在”主 + 多个 backup”上,主挂了由 backup 接管。故障检测基于心跳与 lease;接管过程要重建内存状态(从其他副本同步)。内存系统的挑战:机器重启后内存为空,必须从其他节点拉数据。FaRM 的答案是多副本 + 快速并行恢复。
2.4 FaRMv2:垂直分区与 opacity
SOSP 2019 的 “FaRMv2” 在 FaRM 基础上做了几项重要改动:
- opacity(Transactional Opacity):保证即使 abort 的事务也只读到一致快照,避免”读到不一致中间状态导致业务逻辑崩溃”。这是 Transactional Memory 里的术语,数据库事务里常叫 “consistent reads”。
- snapshot isolation 读:在 OCC 上实现快照隔离读,读不加锁、不验证,代价是读可能稍旧但 abort 率低。
- 更大内存 / 垂直分区:把数据按”热 / 冷”或”读 / 写”做垂直分区,减少每次事务要跨多少机器。
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) | 只存数据,不跑业务逻辑
+-------------------------------+
关键设计:
- compute 与 memory 分离:memory server 只负责存储,自己不跑事务逻辑;compute 节点通过 RDMA 访问远端内存;
- memory server 近乎”裸内存”:CPU 参与最小化;
- compute 节点 stateless:可以随时扩容,本地不 cache 权威数据。
这是 “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]:
- wts:记录最后一次写入的时间戳;
- rts:当前有效读的最远时间戳(logical, 非物理时钟)。
读一条记录,把该事务的 commit ts 往 [wts, rts] 内挤;如果挤不进去,就要延长 rts(租约续借)。写入时要保证 rts 没有超过新写入事务的 ts。
4.2 事务流程
- 事务执行中收集读集、写集;读时记录 wts/rts。
- 尝试给事务选一个 commit ts:必须满足所有读的 wts ≤ commit_ts ≤ rts,所有写的 rts < commit_ts。
- 如果某条读记录 rts < commit_ts,尝试”续借”:联系远端、把 rts 推到 commit_ts。如果远端同意(没有更大的事务占用),成功;否则 abort。
- 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:所有事务向 PD 拿 commit_ts,集中点但协议简单;
- Sundial:每个记录局部决定时间窗,无集中点但协议复杂;
- NAM-DB:共享内存 counter,中间路径——集中但极低延迟。
三者适用的工作负载不同: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.io:等价于 PCIe,做 IO 通信;
- CXL.cache:让设备 cache 主机内存,保持一致性;
- CXL.mem:把设备侧内存映射到主机地址空间,主机可以 load/store 访问。
CXL 3.0(2022)进一步支持跨主机的内存池:多台主机连到同一个 CXL switch,挂载共享的内存池,所有主机可以直接 load/store 访问那块内存,且硬件提供 cache coherence。
这是过去二十年 shared-nothing 盛行以来,第一次有主流硬件提供跨机器的硬件一致性域。
5.2 CXL 对数据库架构的潜在影响
想象一个 CXL pool 配合 4 台数据库 compute 的部署:
- 共享 buffer pool 放在 CXL 内存池,每台 compute 直接 load/store;
- 没有 RDMA 协议开销,延迟接近本地 DRAM(目前 CXL 2.0 延迟大约是本地 DRAM 的 2–3 倍,CXL 3.0 进一步优化);
- cache coherence 由硬件保证,软件不需要做 consistency 协议;
- 故障域:CXL switch 和 pool 的可靠性需要单独考虑,可能需要多 pool 冗余。
这种架构下,很多 RDMA 数据库做的事情(one-sided READ、CAS、版本比较)可以退化成普通内存指令。数据库又可以回到”shared memory + 并发编程”的古典姿势——只是现在每台物理机的 CPU 跨板共享内存。
5.3 现实中的限制
截至目前(2024 年公开资料):
- CXL 2.0 / 3.0 的产品化仍在早期,跨主机 pooling 的 GA 产品少;
- CPU 必须支持 CXL(Intel Sapphire Rapids / Emerald Rapids、AMD Genoa 等);
- 延迟虽然比 RDMA 好,但比本地 DRAM 仍有 2–3× 差距;
- 故障隔离不如 shared-nothing 干净:共享内存里的坏数据可能传染多台主机。
所以 CXL 的前景是“在机柜内提供准本地的共享内存”,不是跨 rack、跨 AZ 的 shared memory。它更像是 NUMA 的扩展,而不是”消灭网络”。
5.4 CXL 下的协议再思考
如果 CXL 成立,前面几个系统的一些设计可以简化:
- NAM-DB 的 timestamp counter:CXL 下就是一个普通的跨机 atomic variable,延迟更低;
- FaRM 的 one-sided READ:直接变成 load 指令,不需要 NIC;
- Sundial 的 lease 更新:lease 字段放在 CXL 共享内存,update 用 atomic;
- PolarDB 的 PolarFS:共享存储可以直接用 CXL 内存池承接一部分热数据。
但 CXL 不会取代 RDMA。CXL 受限于物理距离(机柜内),跨机柜、跨 AZ 仍然要靠 RDMA 或以太网。未来几年最可能的形态是“机柜内 CXL + 机柜间 RDMA + AZ 间 TCP” 的三层网络层级,每层对应不同的延迟预算和协议设计。
5.5 CXL 内存分层的实际部署形态
CXL 在数据库里最现实的几种用法,从保守到激进:
- 单机内存扩展:把 CXL 内存当本地 DRAM 使用,用来扩大 buffer pool / 排序临时区。延迟比本地 DRAM 慢 2–3 倍,但容量可以几 TB,成本低于等量 DRAM。
- 跨 NUMA 但单主机:一台主机多 socket,用 CXL 把远端 socket 的内存抽象成统一地址空间,改善 NUMA 命中。
- 机柜内多主机内存池:几台主机共享一个 CXL pool 里的冷数据区或共享锁表。
- 全共享 buffer pool:几台 compute 共用一块 CXL 内存作为 buffer pool,做读扩展。
- 共享事务状态:进一步把 MVCC 版本链 / 锁表 / timestamp counter 放到 CXL 共享内存,所有 compute 直接 load/store 访问。
工业界目前的主流尝试停在第 1 和第 2 层,研究方向逐步向 3、4 层探索;第 5 层还偏早期,需要数据库引擎深度改动并且硬件故障模型成熟。
5.6 一致性与故障隔离
CXL 硬件提供 cache coherence,但这只解决 “读到旧值” 问题,不解决 “数据被其他主机写坏”。当一块内存被多 host 写入,数据库仍要在软件层做并发控制:
- 如果数据按主机分片,各自写自己的区,用不到跨主机 CAS;
- 如果真共享(如共享 buffer pool),需要全局锁或版本号 + CAS,这时 CAS 的硬件支持比 RDMA CAS 更快(本地指令),但竞争热点仍会成为瓶颈;
- 故障隔离:一台主机”拉崩”共享内存里的关键结构(比如脏 list),其他主机也会跟着崩。需要像传统并发编程一样,对共享数据结构做严格的不变量检查。
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 年数据库可能演进出”每一层都用最合适的技术”的部署形态:
- 单节点内:本地 DRAM + CXL 内存扩展;
- 机柜内多节点:CXL pool 做共享 buffer / 共享锁表;
- 跨机柜:RDMA 承载事务日志 / 跨分片协调;
- 跨 AZ:TCP 承载异步复制 / 备份归档。
RDMA 不会消失,CXL 也不会独占,它们是不同距离段的工具。能把四种路径组合起来的系统,才有可能在”单机性能 + 跨机一致性 + 跨 region 可用性”三者间同时做到很好。
六、选型:RDMA 集群 vs 经典 shared-nothing
6.1 什么时候 RDMA 值得
RDMA 集群的收益主要在三种场景:
- 跨机小事务密集:每秒百万级小事务,单事务跨几条记录。TCP RPC 的 30–100 µs 成为瓶颈,RDMA 能把延迟压下去。
- 分布式 OLAP 或 shuffle:大数据计算里 shuffle 阶段的数据搬运,RDMA 能显著提升吞吐。
- 主备复制链路:主写备以 RDMA write 落到备的内存日志区,commit 延迟可以压到几微秒。
相对的,如果你的业务:
- 单机就能扛住(例如吞吐 < 10 万 tps);
- 事务跨机率低(例如分片设计让 90% 事务单分片);
- p99 要求是毫秒级而不是微秒级;
那经典 shared-nothing + TCP 完全够用,不需要上 RDMA。RDMA 的复杂度、硬件成本、运维负担在小规模下是纯亏损。
6.2 RDMA 集群的硬约束
不是有了 RDMA 网卡就能用:
- 同网段、低跳数:RDMA 对跨交换机跳数敏感,通常部署在同一 pod / 机架组内。
- RoCE vs InfiniBand:RoCE 走 Ethernet,兼容性好但对 switch 的 PFC(Priority Flow Control)配置要求高;InfiniBand 专有网络,性能稳定但成本高。
- 内存管理复杂:RDMA memory region 需要显式注册(memory pinning),大量动态分配会拖慢性能。
- 应用层编程难度高:verbs API 远比 socket 复杂,调试工具链也相对单薄。
在工程上 RDMA 数据库的常见教训:debug 一个诡异性能问题,最后发现是网卡固件版本、交换机 PFC 配置、或者 NUMA 亲和性问题。这些问题在普通 TCP 下很少遇到。
6.3 CXL 的选型建议
现阶段(2024 末)对 CXL 的务实建议:
- 生产谨慎:产品刚起步,生态不成熟,OS 与数据库层的支持都在演进。
- 内存扩展先行:把 CXL 当成”便宜、慢一点的内存”用(single-host、容量扩展),比直接用 pooling 更稳妥。
- 关注机柜内架构:如果未来要构建机柜内 shared-memory 数据库,CXL 是值得押注的方向,但不要今年上线。
- 和 RDMA 一起看:CXL 不替代 RDMA,它是 RDMA 的上游(更短距离、更低延迟)。
6.4 一个可工作的决策流程
在团队里推动”要不要上 RDMA” 时,建议按以下流程走:
- 先做 TCP 基线 profiling:看当前事务延迟的分布,99% 时间花在哪——如果大部分时间在磁盘 IO、锁等待、应用逻辑,那 RDMA 没用武之地。
- 估算事务跨机率:如果分片设计让 95% 事务落在单机,跨机事务总体就不是瓶颈。
- 评估硬件预算:RDMA 网卡 + 低延迟交换机的单节点成本比普通以太网高 2–5 倍。
- 评估团队工程能力:团队里没有熟悉 verbs
API、能读懂
ibv_poll_cq性能问题的人,先别上。 - 做 PoC:选 1–2 个核心事务类型,用 RDMA 改写关键路径,测延迟与吞吐。
- 看收益是否翻倍:如果收益小于 2×,硬件 + 运维的复杂度溢价不值得。
这个流程不华丽,但能把大部分”跟风上 RDMA” 的需求筛掉。真正从 RDMA 中显著受益的业务,普遍是金融交易所、广告实时竞价、大规模 kv-cache 这类对微秒级延迟有商业价值的场景。
七、调优难点
7.1 NIC 与队列调度
RDMA 性能对 NIC 配置极其敏感。常见调优点:
- QP(Queue Pair)数量:每个连接一对 send/recv queue。过少有竞争,过多消耗 NIC 资源。经验数字是每核心 2–4 个 QP。
- completion queue 合并:多个 QP 可以共享一个 CQ,减少 poll 开销。
- inline data:小消息走 inline(直接塞进 WQE),省一次 DMA。阈值通常 64–256 字节。
- doorbell batching:批量 post send/recv,减少对 NIC 的 MMIO 写。
这些配置在不同 NIC 型号(Mellanox ConnectX-5 / 6 / 7)上最优值都不同,需要针对硬件做实测。
7.2 CPU 亲和性与 NUMA
RDMA 的 CPU 开销主要在 poll completion、处理 context。调优要点:
- NUMA 本地:应用线程与 NIC 所在 NUMA node 绑定;跨 NUMA poll 会显著慢。
- interrupt affinity:NIC 的中断绑到专用核,避免和应用线程抢 CPU。
- polling vs interrupt:低负载可以 interrupt,高负载 busy poll。切换阈值要根据延迟预算定。
7.3 一致性与并发控制的坑
- CAS 冲突风暴:如果大量事务竞争同一个 lock word,RDMA CAS 会退化成串行。要用分段锁或者版本号 + 重试。
- one-sided READ 撕裂:远端正在写的同时 one-sided READ,可能读到不一致字节。需要版本号 + 重读验证。
- memory registration 延迟:动态注册的 memory region 首次使用会慢(TLB miss 等),热路径数据要预注册。
- 心跳和故障检测:RDMA 网络故障模式和 TCP 不同,部分链路断开时 RDMA 操作可能 hang 而不是立即报错。
7.4 观测与调试
- 硬件计数器:
ibstat、perfquery能看 NIC 的 packet、错误、重传。 - 软件跟踪:
perf、bpftrace对 verbs 路径能看到 API 调用开销。 - 分布式追踪:RDMA 下每步几微秒,传统 span 采样开销过高。要用 NIC 硬件 timestamp 或专用 ebpf 程序做低开销采样。
7.5 一个常见误区:RDMA 不自动提升吞吐
团队第一次用 RDMA,经常拿”RDMA 延迟 2 µs” 去推算”吞吐应该是 TCP 的 10 倍”,结果实测只快 1.5–2 倍,然后怀疑是不是硬件坏了。实际上:
- RDMA 快的是单次操作延迟;
- 吞吐上限由NIC 的 message rate 和CPU 处理完成事件(CQE)的能力决定;
- 大多数普通 NIC 的 message rate 上限在几百万到一千万 ops/s,超过这个数再怎么 RDMA 也没用;
- 批量(doorbell batching、inline data)与并行 QP 才是提吞吐的关键。
所以使用 RDMA 前要明确目标:是降延迟,还是提吞吐? 两者优化手段不一样,不能简单期望”都能得到”。
7.6 冷热路径的不同选择
一个实用的设计原则:不要用 RDMA 替换所有路径。更好的做法是:
- 热路径 / 微秒敏感(锁检查、事务版本拉取、小 KV 查询):用 RDMA one-sided;
- 中温路径 / 毫秒级(批量 log 复制、心跳、服务发现):用 two-sided RDMA 或 gRPC over RDMA;
- 冷路径 / 对延迟不敏感(配置同步、日志归档、扩容协调):继续用 TCP / HTTP。
这样既享受 RDMA 的红利,又避免把整个系统都绑死在 RDMA 语义上,系统跨机房扩展时也容易降级运行(跨 region 没有 RDMA 时,冷路径继续工作,热路径优雅回退)。
八、小结与展望
RDMA 与 CXL 让”共享内存”这个被判死刑的架构范式以新形态回来:
- RDMA 提供”单边跨机访问远端内存”的能力,让跨机事务延迟从毫秒降到微秒,FaRM / NAM-DB / Sundial 演示了精心设计的 OCC + MVCC + lease 协议如何在 RDMA 下跑到百万级 tps。
- CXL 提供”硬件一致性的共享内存池”,把 shared-memory 的适用范围从”单机 NUMA”扩展到”机柜内多机”,允许软件更多地退化成普通并发编程。
但这两个方向不是要取代 shared-nothing,而是在 shared-nothing 的基础上,给”跨机延迟敏感”的层注入新能力。一个现实的大型数据库架构,未来可能同时具备:
- 分片与复制:保留 shared-nothing 的隔离与扩展性(参考《NewSQL》);
- 机柜内 CXL 共享缓存:把热 buffer pool 放在 CXL pool,多个 compute 节点直接访问;
- 机柜间 RDMA:跨机柜事务与复制走 RDMA;
- 跨 AZ TCP:异步复制、备份、归档。
每一层用合适的协议与硬件,不要求”一种协议通吃所有”。这是接下来几年高性能数据库架构的大致方向。
论文里”百万 tps 每核心”的数字很漂亮,但记住:那是在理想硬件、小规模冲突、单工作负载下测出来的。真实系统里,硬件故障、混合工作负载、运维复杂度会把这些数字打折。在决定是否把 RDMA / CXL 引入生产前,先用第六节的简单判据看你是否真正处在”微秒级延迟有商业价值”的区间。
对研究者与架构师,一个值得长期关注的问题是:随着 RDMA 与 CXL 的成熟,OCC、MVCC、2PL 这些经典协议是否有新的最优形态?FaRMv2、Sundial 已经给出了一些答案,但远不是终点。下一代”shared-memory native” 的事务协议可能会在 2025–2030 年之间逐渐成型,这是数据库领域少有的、底层硬件真的会推动上层协议重新设计的时刻与机遇。对正在选择研究方向的博士生和架构师来说,这是一个难得的机会窗口,值得持续关注与投入。它也提醒我们:架构和协议永远与硬件绑定,脱离硬件谈”最优协议”没有意义。
参考文献
- Dragojević A., et al. FaRM: Fast Remote Memory. NSDI 2014. https://www.usenix.org/conference/nsdi14/technical-sessions/dragojevic
- Dragojević A., et al. No Compromises: Distributed Transactions with Consistency, Availability, and Performance. SOSP 2015.
- Shamis A., et al. FaRMv2: Fast General Distributed Transactions with Opacity. SOSP 2019.
- Zamanian E., et al. The End of a Myth: Distributed Transactions Can Scale. VLDB 2017. https://www.vldb.org/pvldb/vol10/p685-zamanian.pdf
- 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.
- Compute Express Link Consortium. CXL 3.0 Specification. 2022. https://www.computeexpresslink.org/
- Kalia A., Kaminsky M., Andersen D. G. Design Guidelines for High Performance RDMA Systems. USENIX ATC 2016.
上一篇:【数据库研究前沿】Disaggregated DB 合集:Socrates、PolarDB、Taurus 的共同模式
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【数据库研究前沿】系列导论:从 System R 到 AI-Native 的 2026 研究地图
以 System R、Postgres、Bigtable、Spanner、Snowflake 等关键节点串起 50 年数据库史,勾勒 2026 年 AI-Native、向量检索、HTAP 云原生、新硬件、隐私计算、新范式、方法论七条主线,并给出 25 篇系列文章的完整阅读地图。
【数据库研究前沿】CXL 3.0 与内存池化:对缓冲池与共享内存模型的重塑
从 CXL 1.1 到 3.0 的协议演进、Type 1/2/3 设备分类,到 Pond、TPP 两篇 ASPLOS 2023 论文展示的云内存池化实践,再到 PostgreSQL / MySQL 在分层内存下的 buffer pool 调参方向,梳理 CXL 对数据库共享内存模型的重塑路径。
【数据库研究前沿】如何读数据库顶会论文:SIGMOD/VLDB/CIDR 阅读路线
从顶会定位、检索渠道、三遍读法到工业与学术论文的辨别方法,给出 2023–2025 年数据库领域可信必读二十篇,并配套 CMU 15-721、Stanford CS 245 等公开课清单。
【数据库研究前沿】学习型查询优化器:Neo、Bao、Balsa 到 LLM-CBO
系统梳理 Neo、Bao、Balsa 以及新兴 LLM-assisted 查询优化的核心思想,结合 PostgreSQL pg_hint_plan 给出一条可落地的 learned QO 工程路径