社区新闻站 Lobsters 上周完成了一件筹划多年的事:把生产数据库从 MariaDB 换成 SQLite。主内容库文件约 3.8GB,另外还有 1.1GB 的缓存库、218MB 的队列库,以及仍在增长的 555MB rack_attack 防刷库。整套应用现在跑在一台 VPS 上,开发者在论坛里说 CPU 和内存占用都降了,站点更快,MariaDB 那台服务器下线后成本直接减半。
这个说法读起来像一次干净利落的周末工程。但翻一下这个项目的代码提交记录会发现,事情没有那么顺。
三次交锋,不是一次搬家
Lobsters 团队从 2018 年就在讨论要不要甩开 MariaDB,最初的目标其实是 PostgreSQL,图的是降低内存占用、改善全文搜索。这个念头拖了将近七年,直到去年团队才转向调研 SQLite。
真正动手之后,故事分成三段。第一次尝试(PR #1705)加了全文搜索表、把评论排序逻辑挪到 Ruby 端处理,但最终没有合并。第二次(PR #1871)合并了,也部署到了生产环境——结果当天就因为"性能不达标"被紧急回滚,维护者留下的记录是调试时间耗尽,没有公布任何量化指标。直到第三次(PR #1927),团队才真正把 SQLite 稳定地跑起来。
第二次尝试留下的开发环境基准测试其实数据不错——某个故事页面 SQLite 比 MariaDB 快十几毫秒,主页也略快。但开发环境的小样本测试没能预测生产负载下的表现,这次上线当天回滚,正好给"本地测得快就靠谱"这种判断打了个反证。
真正救场的是补丁,不是数据库名字
第三次能成,靠的不是换了个数据库这么简单。团队排查发现,一个评论数超过一千条的故事页面,查询要耗时约 150 毫秒;只要把评论正文这类大字段从查询里裁掉,时间能降到约 30 毫秒。问题出在结果集大小和对象物化开销上,不是 SQLite 天生慢。
团队最终修复了一个 N+1 查询问题,增加了索引,并用一份 16 万篇文章、30 万条评论的合成数据集做了压测,5 个 Puma worker、5 并发跑 1000 次请求:
| 页面 | 均值 | 中位数 | 最大值 |
|---|---|---|---|
| 主页 | 60ms | 58ms | 150ms |
| 故事页 | 45ms | 43ms | 141ms |
- 结论.这次真正起作用的是查询优化和索引,不是"SQLite 换掉 MariaDB"这件事本身。同样的补丁放在 MariaDB 上,大概率也能提速。
生产环境的 SQLite 配置也不是开箱即用:团队手动开启了 WAL 日志模式、把同步策略调成 NORMAL、设置了内存映射大小和缓存页数,还打开了外键约束。这些参数调优,恰恰是很多"单文件数据库"宣传里被省略的部分。
- 提醒.所谓"开箱即用"在这个案例里并不成立,稳定运行是手动调参和查询重写共同换来的,照搬到别的项目未必立刻见效。
"成本减半"目前还只是一句主观感受
原帖里"CPU 下降、内存下降、成本减半"的说法,目前查不到任何官方发布的量化对比数据——没有 VPS 配置、没有 MariaDB 原库体积、没有内存占用曲线,全部是开发者在论坛里的轶事性描述。这不代表数据不真实,但意味着现在还没法拿它当成可复制的基准。
台前一个周末,台后三次交锋——这才是这次迁移最该被记住的部分。
对正在评估"单 VPS + 中等规模社区站点"这条路的团队来说,Lobsters 这次给出的经验不是"SQLite 更快",而是查询层面的裁剪和索引往往比换数据库引擎更管用。至于 SQLite 单文件、单写入者的锁机制在写入并发上升后会不会成为新瓶颈,还得看这套架构长期跑下去的表现——目前还看不清。
