有时候一个随手看到的Reddit帖子,会把我拖进整整一个晚上的兔子洞里,这就是那样的一个夜晚。有人发帖讨论像YouTube这类公司是怎么给数据库做扩展的,评论区挤满了说自己完全搞不懂一个系统怎么能扛住那么大负载的人。这个问题一直萦绕在我脑子里,于是我开始查资料。
YouTube到底是怎么做的
查下去才发现,YouTube跑的是MySQL,用Vitess做分片。Vitess最初就是YouTube自己开发的一套系统,让MySQL能够跨数千个分片做水平扩展,同时在应用层看起来依然像是单一数据库。看到这里,我立马回头审视自己的架构,问自己:我为什么没这么干?
盘点一下自己实际在跑什么
我有两台服务器。一台在Docker里跑着一个共享的PostgreSQL实例,服务着好几个小网站。另一台专门给Immich用,用的是带pgvector扩展的Postgres,用于照片的相似度搜索。唯一跑MySQL的是我妈的网站doc-agnes.com,用WordPress搭的,那个我不敢碰。我目前还没有足够的信心在不冒着丢数据风险的情况下迁移一个正在跑的WordPress数据库,而且老实说,我也不太确定WordPress跟Postgres配合得到底好不好。
掉进Citus和Aurora的坑
于是我去查Postgres有没有自己的"Vitess"。查到了Citus,一个用于分布式/分片Postgres的扩展,但从我找到的大多数对比来看,在纯粹的水平MySQL式扩展上,它比Vitess要慢。这让我开始嘀咕:也许我一开始就该用MySQL加Vitess来搭,而不是Postgres。
然后Aurora进入了视野。AWS没有依赖标准的MySQL或Postgres内核,而是在Aurora底层自建了一套存储引擎,那些数字确实让我印象深刻。在我读到的不少基准测试里,它都跑赢了另外两者。但当我让Gemini把这三者放在一起权衡时,它指出Aurora的标准配置在持续极高写入吞吐量下会开始吃力(粗略数字大概在每秒15万次写入左右会碰到瓶颈),这让它在真正大规模、写入密集的负载场景下打了点折扣。
接着我比较了运维复杂度。MySQL加Vitess的运维难度遥遥领先,因为分片逻辑、代理和连接处理基本都要自己搞定。Citus作为一个Postgres扩展,相对来说轻松得多——它是搭建在我已经熟悉的数据库之上,而不是要我从头手工拼一整套全新的分布式系统。就是在这一刻,我才明白为什么现在这么多公司默认选Postgres:不一定是因为它在每项基准测试里都更快,而是因为运维成本低得多。(AWS较新的分布式Postgres产品Aurora Limitless看起来也挺扎实的。)
一次市场份额的小插曲
在这个漩涡的某个环节,我顺手查了一下数据库市场份额,发现Postgres在开发者调查排名里位居榜首,MySQL紧随其后——不过具体排序会随你看的是哪种调查而变(安装基数,还是开发者自己说在用/想用的),排名会互换。不管怎样,Postgres现在的势头是显而易见的。
Redis也被提到了。我一直以为它纯粹就是一个缓存层,Gemini告诉我我大体上没错,但技术上讲它其实是一个完整的内存数据库,而不只是坐在某个数据库前面的缓存。它的速度来自RAM比磁盘快得多这一点。我此前模糊不清的地方是,Redis其实仍然可以在后台持久化到磁盘(快照,或者一份只追加写入的日志),所以重启并不一定意味着数据全部丢失。它并不像我以为的那样纯粹是临时性的。
现实检验
读完这么多东西、做完这么多对比、对着自己大概永远都用不上的架构嘀咕了半天之后,我忍不住笑了自己一下。我根本没有YouTube那种问题。每个项目大概就四个用户,还都是我真正认识的人;我存的最重的东西就是Immich里的照片。没有分片,没有Vitess,也没有每秒15万次写入。只有我自己、Postgres,以及一份非常小、非常知足的数据集。不过好在,现在起码理论我是懂了。