SQLite 的 “单文件即库” 设计带来极致简单,却长期被贴上 “玩具库” 标签:没有原生机架级复制,也没有时间点恢复。Litestream 用一行额外进程把 WAL 日志流式转发到对象存储,把 SQLite 原地升级为零依赖、秒级 RPO的 “伪分布式” 数据库,而应用层无需改一行代码。
WAL 拦截:把事务日志变成复制流
Litestream 并不动 SQLite 内核,而是在用户态注册一个轻量 VFS shim,拦截 xWrite 调用:
- 事务提交时,WAL 帧先落本地磁盘;
- shim 把新帧打包成自定义 LTX(Lite Transaction)文件,含事务 ID、滚动 CRC64 校验和与页数据;
- 通过 HTTP 多路复用通道并行推送到 S3、Azure Blob、GCS 或 SFTP;
- 副本节点按 TXID 顺序重放 LTX,即可保持与主库字节级一致。
整个流程延迟通常在 100–300 ms,网络抖动时退回到 1 s 级,仍远低于传统备份脚本的小时窗口。
单写模型:副本只读,故障秒切
SQLite 的单写锁模型在 Litestream 里被原样保留:主库唯一写,副本库以 SQLITE_OPEN_READONLY 打开,杜绝脑裂。当主节点宕机,只需在任意副本执行
litestream restore -o /var/lib/app.db s3://backup-bucket/app.db
恢复 1 GB 数据库平均 5 秒,RTO 与容器启动时间同级;RPO 由 sync-interval 决定,最小可设 100 ms,生产实测 99 线 800 ms。
5 行 YAML 配置: sidecar 即高可用
# /etc/litestream.yml
dbs:
- path: /var/lib/app.db
replicas:
- url: s3://backup-bucket/app.db
retention: 24h # 历史 LTX 保留时长
sync-interval: 1s # 复制间隔
compression: gzip # 可选压缩
进程内存常驻 <5 MB,CPU 占用低于 1%;systemd 一次启动,随后透明复制。对 Kubernetes 场景,可把 Litestream 作为 sidecar 注入同一 Pod,本地通过 emptyDir 共享 db 文件,实现 “容器级主从”。
性能边界:1 k tps 是舒适区
Litestream 复制带宽消耗 ≈ 写入字节数 ×1.2(含元数据)。在 NVMe 盘上,SQLite WAL 单线程写上限约 1 000 tps / 连接;若业务持续高于此值,需分库或回归 Postgres。读性能不受任何影响,副本可承担只读流量,实现零网络延迟的本地查询。
可落地 checklist
| 任务 | 命令 / 脚本 |
|---|---|
| 一键安装 | wget -O litestream.tar.gz https://github.com/benbjohnson/litestream/releases/latest/download/litestream-linux-amd64.tar.gz && tar -C /usr/local/bin -xzf litestream.tar.gz |
| 完整性巡检 | sqlite3 /var/lib/app.db "PRAGMA integrity_check;" |
| 监控复制延迟 | `echo $(( $(litestream db -config /etc/litestream.yml /var/lib/app.db |
| 灾难演练 | 每月随机 kill -9 主进程,验证 sidecar 是否 30 s 内自动重启并完成 restore |
小结
Litestream 用最小侵入把 SQLite 的 “单文件” 优势保留,同时赋予它云级复制与恢复能力:无状态 sidecar、对象存储即副本、秒级 RPO。对于读多写少、单节点即可装下的 SaaS 场景,它让研发团队在不引入分布式复杂度的前提下,获得企业级备份与容灾底线。若你的写入峰值 <1 k tps,下次立项不妨给 SQLite + Litestream 一张门票 —— 你可能因此省下一条 Postgres 集群的账单。
参考资料
[1] 掘金:《Litestream:革新 SQLite 的轻量级数据库复制系统》,2025-04-21