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

【FoundationDB 内核】SSD Engine 与 Redwood:从 SQLite 派生到版本化 B-Tree

文章导航

分类入口
databasestorage
标签入口
#foundationdb#redwood#ssd-engine#btree#sqlite#rocksdb#storage-engine#sigmod2021

目录

第 11 篇 把 Storage Server 钉成「按版本服务读、异步应用 TLog」的角色。本篇下沉到进程内引擎:磁盘上到底是什么结构,为何可以没有「SQLite 式本地事务 WAL」来承担分布式提交,以及 Redwood 相对旧 SSD Engine 改的是哪一层假设。

本篇重写站内 SQLite 亿级行 或 SQLite 内核全文;只把「FDB 借用过什么、丢掉什么」说清楚。也不把 LSM vs B-Tree 写成无 workload 的快慢排名——对照 rocksdb 系列 时只谈放大因子与职责边界。

本文是「FoundationDB 内核」系列第 12 篇(共 18 篇)。上一篇Storage Server下一篇故障恢复→ 系列目录

版本锚定:FoundationDB 7.x。论文描述以 SIGMOD 2021 时的 SQLite 派生引擎为准;Redwood 以 7.0 Release Notes、Configuration 中的 ssd-redwood-v1 与源码/设计讨论为准。无本机引擎 benchmark 则不下吞吐结论。


一、系统边界:引擎不是分布式事务的提交者

先固定不变式:

  1. 提交耐久性在 TLog(第 10 篇)。
  2. Storage Engine 负责把已排序的 mutation 物化为可点查 / 范围扫的结构,并支持短窗口多版本读。
  3. 因此引擎侧不需要再实现一套与分布式 commit 对等的「本地 ACID 事务协调」;它需要的是高效页管理、崩溃后能从 TLog 追平、以及与 5 秒 MVCC 窗口匹配的版本策略。
flowchart TB
  subgraph Cluster["Cluster contracts"]
    TLog["TLog durable commit"]
    Ver["Sequencer versions + 5s window"]
  end
  subgraph Engine["Per-Storage engine"]
    Pages["B-Tree / pager"]
    MV["Versioned reads"]
  end
  TLog --> Pages
  Ver --> MV
  Pages --> MV

若把 FDB Storage 理解成「每节点跑一个完整 SQLite 数据库事务」,会误判恢复与备份边界:节点丢盘后,权威 redo 仍在 Log System,Data Distributor 可重建责任范围(论文与 Architecture)。


二、谱系上半段:SQLite 派生的 SSD Engine

2.1 论文中的表述

SIGMOD 2021 §2.3.2:每个 StorageServer 上的存储引擎是 modified version of SQLite,增强包括更快的 range clear、把删除推迟到后台、以及适配异步编程。§2.4.4 进一步写明结构组合:

官方 Architecture(7.x 文档仍保留历史表述):SSD storage engine 基于 SQLite 的 B-Tree;并预告 Redwood 替换方向。Configuration 里 ssd 引擎描述为面向 SSD 优化的 B-Tree,删除后空间回收可延迟进行。

2.2 从 SQLite 拿走什么、不拿走什么

社区与开发讨论(Forum new storage engine ideas 等,作 B 级动机线索)常列出 SQLite 页结构对 FDB 工作负载不友好的点:内部节点存完整 KV、缺少前缀压缩、大 value 溢出页链、页级 WAL 导致写放大等。FDB 的取舍是:

拿走 不拿走
B-Tree 页与索引查找 SQL 解析、查询计划、sqlite 语句事务 API
可靠页分配 / 空闲页管理思路 「SQLite WAL 即分布式提交」语义
单机崩溃恢复页一致性能力 跨键分布式隔离(由 TS+LS 负责)

站内 SQLite 文章讨论的是嵌入式库与分析型扫描等议题;本系列只关心:作为 FDB 的页存储后端,它把随机点读做成 B-Tree 查找,并把版本问题大部分留在内存窗口。这是历史主线,不是对 SQLite 产品的全面评价。

flowchart LR
  SQ["SQLite B-Tree + SQL stack"] --> Strip["Strip SQL / statement txn API"]
  Strip --> SSD["FDB SSD Engine"]
  SSD --> MemMV["In-memory MVCC window"]
  SSD --> DiskBT["On-disk unversioned B-Tree"]

2.3 论文评价之外的运维现实

SIGMOD 2021 写作时主线仍是 SQLite 派生引擎;Redwood 在开源树中实验更早,产品化叙事在 7.0 Release Notes 落地。阅读旧博客时若只见「FDB = SQLite」,需要按版本校正。反之,把 7.x 集群一律当成「已经 Redwood」也不对——Configuration 里引擎是显式选项,默认/存量可能仍是 ssd

切换引擎属于存储子系统变更,应纳入变更窗口与回滚计划;本系列第 16 篇讨论运维边界时不会用无来源的「一键无感」承诺。

三、谱系下半段:Redwood

3.1 产品定位

7.0 Release Notes:首次发布 Redwood Storage Engine,定位为相对 SQLite 引擎更高吞吐、更低写放大的 B-Tree 引擎(官方措辞;无本系列复现则不当作你的硬件结果)。Configuration:通过 ssd-redwood-v1 选择;与 ssdssd-rocksdb-v1memory 并列。

PR #819(初始实验版本)描述 Redwood:在多版本 pager 上的多版本 B-Tree,持久化旧版本 key,并使用前缀压缩。Forum 讨论将其概括为前缀压缩 B+Tree 方向,动机包括写放大、空间、以及更长只读事务的可能性(后者是否升到系统级默认契约,以 Limitations 为准,见下)。

3.2 相对 SSD Engine 的机制差分

维度 SQLite 派生 SSD(论文时代主线) Redwood(7.x 选项)
树形态 SQLite B-Tree 血统 面向 FDB 的 B-Tree / B+Tree 实现
版本 磁盘未版本化 + 内存 MVCC 引擎内多版本 + 前缀压缩等
写路径角色 物化离开窗口的提交 同样不替代 TLog 提交
配置名 ssd ssd-redwood-v1

Architecture 仍写客户端默认约 5 秒版本窗口与 transaction_too_old。引擎能持久更多历史,不等于集群已取消 Known Limitations 中的长事务设计限制。把「Redwood 支持更长读」理解成「可以随便跑分钟级读写事务」,会与事务系统窗口冲突——除非文档对特定 API / 模式另有明确放宽。

Forum 讨论(B 级)还提到:前缀压缩与可配置保留旧版本,有望用磁盘空间换更长只读——这是引擎动机,落地时仍受事务系统窗口、磁盘预算与 GC 策略约束。写内核文时应把「动机」与「已默认交付的契约」分开;本系列以 Known Limitations 与 Architecture 的硬语义为准。

3.3 RocksDB 引擎选项的位置

Configuration 提供 ssd-rocksdb-v1。这表示 FDB 允许在 Storage 角色下挂 LSM 后端,但不改变 Unbundled 契约:LSM 仍然消费 TLog 流,不接管 Sequencer/Resolver。与站内 rocksdb 系列的关系是单机引擎对照,不是「FDB 变成了 TiKV」。TiKV 的 Raft+Percolator 与 FDB 的 TLog+OCC 仍是上一层的分叉(第 8–9 篇)。

flowchart TB
  SS["Storage Server role"] --> E1["ssd SQLite-derived"]
  SS --> E2["ssd-redwood-v1"]
  SS --> E3["ssd-rocksdb-v1"]
  SS --> E4["memory"]
  TLog["TLog mutations"] --> SS

四、页布局、版本化与「无本地事务 WAL」在说什么

4.1 页与版本

对 SQLite 派生引擎:页上主要是最新物化状态;版本链在内存 redo / MVCC 结构中。对 Redwood:版本进入 pager/树结构,前缀压缩降低内部节点与叶上的键开销——这直接回应当初对「内部节点存满 KV、无前缀压缩」的批评。

本篇不绘制未核对源码行号的页格式比特图;实现以 fdbserver 中 Redwood 相关代码与官方 Redwood 文档页为准。读者若要核对,应从发布版本的源码树检索 Redwood pager / B-Tree 模块,而不是从二手幻灯片反推。

4.2 「无本地事务 WAL」的准确含义

容易说滑:

Memory 引擎用内存结构 + 仅在重启时读取的 append log(Architecture)把同一哲学推到极端:耐久性仍然不在「内存引擎本地」,而在集群日志与复制。

4.3 配置层如何选择引擎

Configuration 文档把引擎写成集群存储子系统选项:数据集大于内存时需 SSD 类引擎(ssd / ssd-redwood-v1 / ssd-rocksdb-v1);memory 适用于能放入内存的工作集。旋转磁盘上跑 SSD 类引擎被 Known Limitations 明确不推荐。这些是部署约束,不是事务隔离选项——换引擎不会把默认隔离从严格可串行化改成 SI。

从 SQLite 派生引擎迁到 Redwood,涉及数据重写 / wiggle 等运维路径(7.x 引入 perpetual storage wiggle 等,见 Release Notes);本篇不展开操作手册,只标明:引擎切换是 Storage 角色内的迁移,不是改写 Client API。


五、与 LSM 的机制对照(不排名)

问题 B-Tree 路线(SSD/Redwood) LSM 路线(RocksDB 选项 / TiKV 主线)
写放大 页更新 / 分裂;Redwood 目标是降低相对旧 SSD 的 WA MemTable → L0 → 分层 compaction
读放大 通常树高次查找;版本策略影响扫描 可能跨多层与 bloom;compaction 策略敏感
与 FDB 契合点 论文目标负载偏读多、小读写、低争用 适合高写吞、可接受 compaction 运维时
版本 FDB 另有 5 秒系统窗口 TiKV 等用 CF 内时间戳链,窗口策略不同

O’Neil et al. 的 LSM 论文与后续 leveled/tiered 争论属于 rocksdb 系列主战场。这里只需记住:FDB 默认叙事长期是 B-Tree Storage + 分布式 TLog;引入 RocksDB 引擎是选项,不是把系列改写成 LSM 内核课。

对「读多、点查、低争用」的论文目标负载,B-Tree 点查放大通常更直观;对「持续重写大 value、宽范围删除」类负载,LSM 或 Redwood 的具体实现差异都可能主导结果——必须实测才能选型,本篇拒绝给排名。


Testing Storage Server(TSS)允许在同一负载下对比「不受信任」引擎与当前引擎的结果,且官方强调对耐久性与正确性零影响、对性能影响最小(7.0 Release Notes 口径)。对 Redwood 推广而言,这意味着引擎正确性可以走「影子对比 + 模拟」双轨,而不必先赌全集群切换。本系列第 14 篇谈确定性模拟时会接到同一测试文化;本篇只需记住:存储引擎替换在 FDB 里是一等公民工程问题,不是私有补丁。

5.1 何时不该从本篇推出选型结论

允许的结论只有机制层:FDB 可以在 Storage 角色挂 B-Tree 或 LSM 后端;分布式提交与隔离不随后端切换而改写;Redwood 针对的是旧 SQLite 派生引擎的页与版本假设。其余一律留给实验台账。

六、学术谱系、工程间隙与开放问题

谱系:SQLite 自身来自嵌入式 RDBMS 传统(D. Richard Hipp);FDB 把它降维成页存储。Redwood 是系统内重生的多版本树,而不是「再嵌一个 SQLite」。测试上,7.x 引入 Testing Storage Server(TSS)等机制,允许在信任边界内对比引擎结果(Release Notes)——这是存储引擎演进与确定性模拟文化的交叉点,细节见第 14 篇。

工程间隙:官方用「更高吞吐、更低写放大」描述 Redwood,但未在本系列环境复现;不同页大小、压缩、工作负载会改变结论。把 Release Notes 营销句写进容量规划会翻车。持久化更多版本还带来空间与 GC 运维面,论文时代「磁盘未版本化」反而让版本 GC 主要落在内存窗口——利弊随 Redwood 翻转。

开放问题:在何种更新局部性下,Redwood 的前缀压缩 B-Tree 稳定优于挂载的 RocksDB 引擎?何时应反过来?这需要受控对比实验与清晰的读改写混合比;开放入口是 Configuration 引擎说明 + 自建 TSS/对比负载,而不是论坛轶事。


七、常见误解

误解 事实
「FDB 内部跑完整 SQLite 数据库」 历史主线是派生 B-Tree 页引擎,无 SQL 栈
「Redwood 取消了 5 秒限制」 事务系统 Limitations 仍在;引擎能力 ≠ 默认契约取消
「换 Redwood 就改变严格可串行化」 隔离由 TS+版本+OCC 决定,不由叶节点布局决定
「没有本地 WAL 等于不安全」 耐久性在 TLog 复制;引擎负责物化
「B-Tree 一定比 LSM 快」 取决于读写比、value 大小、压缩与 compaction;无实测不排名
「换引擎等于换一致性模型」 一致性由 TS+LS 契约决定;引擎只物化

八、小结

三句话小结

  1. SSD Engine 谱系来自去掉 SQL 的 SQLite B-Tree:磁盘未版本化物化 + 内存 MVCC,匹配 TLog 提交与 5 秒窗口。
  2. Redwood 在 7.x 以 ssd-redwood-v1 提供多版本、前缀压缩的 B-Tree 替代,目标是写放大与空间等引擎层问题,不替代 TLog/Resolver。
  3. 与 RocksDB/LSM 的选择是 Storage 角色内的实现选项;分布式事务与恢复哲学仍由 Unbundled 上层定义。

下一篇进入 故障恢复:角色招募、恢复 epoch,以及写暂停与读可用边界。


上一篇Storage Server

下一篇故障恢复:角色招募与恢复 epoch

返回 系列目录


若阅读路径来自 distributed/39,请忽略其中未在本系列复现的单节点 QPS 表,只保留「B-Tree / Redwood」这一引擎线索;性能数字以你自己的测量或带完整口径的官方 benchmark 文档为准。

文末核对提示

本节补记:机制结论以 SIGMOD 2021 与 FoundationDB 7.x 官方 Architecture / Developer Guide / Known Limitations 为准;若源码字段名随小版本重命名,以对应 tag 的 fdbserver 实现为准,不把过时幻灯片当契约。

阅读本篇时建议同时打开系列 index 中的依赖图:本篇上承写路径与版本分配,下接恢复与排障;不要孤立地把单角色文档当成完整正确性证明。

本节补记:机制结论以 SIGMOD 2021 与 FoundationDB 7.x 官方 Architecture / Developer Guide / Known Limitations 为准;若源码字段名随小版本重命名,以对应 tag 的 fdbserver 实现为准,不把过时幻灯片当契约。

阅读本篇时建议同时打开系列 index 中的依赖图:本篇上承写路径与版本分配,下接恢复与排障;不要孤立地把单角色文档当成完整正确性证明。

参考资料

论文(A 级)

  1. Zhou et al. FoundationDB…. SIGMOD 2021(§2.3.2 SQLite 派生引擎、§2.4.4 未版本化 B-Tree + 内存 MVCC)。
  2. O’Neil, Patrick et al. The Log-Structured Merge-Tree (LSM-Tree). Acta Informatica 1996(LSM 对照奠基;不展开)。

官方文档(A 级)

  1. FoundationDB 7.x, Configurationssd / ssd-redwood-v1 / ssd-rocksdb-v1 / memory
  2. FoundationDB, Release Notes 7.0 — Redwood 首次发布表述。
  3. FoundationDB 7.x, Architecture — Storage engine 历史表述与 memory 引擎。

源码 / 设计(A 级)

  1. apple/foundationdb PR #819 — Redwood 初始描述(multi-version B-Tree、prefix compression)。

站内对读

  1. 第 11 篇 Storage Server第 10 篇 TLog
  2. SQLite 单篇(不重复)、rocksdb 索引
  3. distributed/39(引擎一行对照;不复制其 QPS 表)。

同主题继续阅读

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


By .