← 文章 / 数据与数据库
Hacker News 2小时前 · 2026-10-24 13:40:12 · 7 阅读

分布式 SQLite 的十二年历程

2014年9月,我发布了一篇短文,正式介绍了rqlite。思路很简单:在 SQLite 前加一层 Raft 日志,把每次写入都复制到集群里,这样即使某个节点挂掉,数据也不会丢失。那个周末,源码就推上了 GitHub。就我所知,那是第一个把 Raft 和 SQLite 结合起来的开源系统。当时没人这么做,此后好几年也没人尝试。

如今,“分布式 SQLite”已经成了一个品类,里面有一打项目,其中几个拿了风投,两个被收购了。现在写这个品类的人,往往把故事起点放在2021年,但我想写下那个从2014年讲起的版本。因为我全程都在。

2014:rqlite

需求很具体。当时我在 jut.io 参与的一个集群化系统,需要一小块关系型存储,而“该由哪个节点存”这个问题没有好答案。用共识协议复制 SQLite 正好解决了它。工作中我们选了别的方案,但我还是继续在做 rqlite,因为这个问题是通用的,而解法很小。第一版用的goraft,也就是当时InfluxDB和etcd用的那套库(差不多同一时间,我加入了 InfluxDB 做核心开发)。2016年初,我把它换成了Hashicorp 的 Raft 实现,rqlite 沿用至今。

最关键的架构决策在那时已经敲定,并沿用至今:rqlite 是一个 CP 系统。写入操作必须经由 Leader 执行,且需获得多数节点确认;少数派在分区状态下会拒绝写入。其余所有细节,包括 HTTP API、读一致性级别 以及 快照机制,皆由此逻辑派生。

2014 年之前及同期项目

为了保持客观,有两点值得一提。出于诚实用心,Expensify 在自身基础设施内部通过 Paxos 类协议复制 SQLite 数据已有数年历史;他们后来将其作为 Bedrock 在 2016 年开源。同时,基于 Erlang 构建的 ActorDB 也出现在 rqlite 前后,它为每个 “actor” 配备独立的 SQLite 数据库,并通过 Raft 实现复制。尽管这两个项目均未在各自发源地获得广泛采用,但它们都表明当时的技术圈已流行起这种分布式 SQLite 的思路。rqlite 的贡献在于将其打造为一个独立的、通用的、开源的组件,让任何人都可以随意部署。

2017 年:dqlite

Canonical 开发了 dqlite,旨在为 LXD 及后续的 MicroK8s 提供嵌入式复制存储,从而免去运行 etcd 的开销。Mark Shuttleworth 曾亲自给我打过电话沟通,希望 rqlite 能适配其需求,但最终因架构差异未能融合。dqlite 最初用 Go 编写,后重写为 C 语言,并内置自研的 Raft 库。dqlite 是意图上与 rqlite 最相似的项目,两者核心差异在于打包形式:dqlite 是嵌入式库,而 rqlite 是独立运行的服务器。Canonical 需要的是集成在产品内部的数据库,而我追求的是运行在任意产品旁边的数据库。

2021 年:Litestream 与思路转变

Ben Johnson(我们曾一起在 InfluxDB 共事)于 2021 年初发布了 Litestream。Litestream 完全不用共识机制,它监控 SQLite 的 WAL,并将其流式传输到 S3,几乎零成本地为单节点 SQLite 数据库提供容灾能力。Ben 的观点是:大多数应用并不需要集群,它们只用一台机器,需要的只是一旦机器挂了能恢复数据的手段。对大量应用来说,他是对的。此后几年兴起的“SQLite 就够了”运动——各种博客文章和技术演讲——很大程度上要归功于这一论点。

Litestream 和 rqlite 回答的是不同的问题。Litestream 解决的是:机器挂了怎么办?rqlite 解决的是:机器挂了,而且我等不及从备份恢复怎么办?前一个问题更常见,后一个问题则是人们来找 rqlite 时真正想解决的。

Fly.io 在 2022 年招入了 Ben,推出了 LiteFS。它在文件系统层面复制 SQLite,并借助 Consul 实现租约机制。这是第一次尝试把 SQLite 复制做成平台内置能力,而不是需要用户自己部署的东西。最后还有个有趣的转折:Litestream 反过来启发了 rqlite v8.0 处理 SQLite WAL 的方式。

2022:分支与扩展

2022 年有两个项目走了 rqlite 和 Litestream 都没走过的路。cr-sqlite 以扩展的形式给 SQLite 加上了 CRDT,让多个写入方可以各自偏离、再相互合并,无需 leader。这占据了设计空间中的 AP 一角,适合 local-first 应用——对这类应用来说,rqlite 的 CP 保证反而是累赘。

libSQL 直接 Fork 了 SQLite 源码。ChiselStrike(后来的 Turso)试图修改引擎内部,但 SQLite 项目不接受外部贡献,不愿改动。他们基于这个 Fork 构建了一个托管服务,支持边缘端副本。Turso 据此获得了风投资金,2026 年 被 Supabase 收购。

几乎同一时期,SQLite Cloud 出现,提供基于 Raft 复制的托管 SQLite 服务。该项目最接近 rqlite 的原始设计,封装成了云服务。

2022 年起:平台化

Cloudflare 在 2022 年发布了 D1,将 SQLite 作为边缘网络中的无服务器数据库,随后在 Durable Objects 中内置 SQLite 存储。这是一种复制型 SQLite 托管产品,来自一家不需要向你解释其工作原理的公司。Turso 的服务形态与此类似。该类别已经从“自运行工具”变成了“购买商品”。

十二年的启示

我认为主要有三点。

核心思路是对的。以 SQLite 作为存储引擎,在外部添加复制功能,这一模式被至少八个不同团队基于不同需求和协议重新发明过。没人找到停止这种做法的理由。

设计空间有三个角落,且按顺序出现。首先是共识机制(rqlite、dqlite):一个主节点,强一致性,集群架构。其次是流式复制(Litestream):单写入者,低成本恢复,无集群。最后是合并(cr-sqlite,以及 Local-first 运动的组成部分):多写入者,最终一致性。每种方案都适合解决不同的问题,大多数争论其实是用户之间关于“究竟该问什么问题”的争执。

最后,钱流向了平台。rqlite、dqlite 和 Litestream 是开源免费的。而那些融资成功或被收购的项目,则是将复制型 SQLite 变成收费服务的一方。这是基础设施类技术的常规命运,我并不介意。但值得注意的是,这个想法在有人出售之前,已开源长达八年。

rqlite 依然健在。它做的仍是 2014 年那件事——只不过做得更好了。如今,若你寻一套容错的、可自托管、能彻底吃透、且无需向谁付费的关系型数据库,它仍是首选。十二年过去,我对自己在故事中的这个位置感到满意。

原始来源: Hacker News

评论 (0)