
大家好,我是Tony Bai。
在 Uber 这样体量的公司,其核心在线存储系统不仅要处理 PB 级的海量数据,还要以毫秒级的延迟响应每秒上亿次的请求。这一切是如何实现的?本文将深度整合 Uber 工程团队这几年公开发布的三篇文章,和大家一起穿越其核心存储架构的十年演进史:从最初为解决 MySQL 扩展性难题而生的 Schemaless,到拥抱 SQL 和强一致性的分布式数据库 Docstore,再到最终通过集成式缓存 CacheFront 将读取性能推向 1.5 亿 QPS 的极致。这是一个关于在 MySQL 之上构建分布式巨兽的真实故事,充满了工程上的权衡、妥协与创新。
Schemaless 的诞生——戴着镣铐的舞蹈
故事的起点,是 Uber 早期对 PostgreSQL 的依赖,以及随后因性能和扩展性问题向 MySQL 的迁移。然而,即便是 MySQL,在面对 Uber 业务爆炸式增长带来的写入和分片(sharding)压力时,也很快捉襟见肘。Schemaless——Uber 的第一个自研存储系统——正是在这样的背景下诞生的。
核心动机:解决 MySQL 的扩展性瓶颈
Schemaless 的设计目标非常明确:在 MySQL 之上构建一个水平可扩展的、对开发者透明的分片层。它并非要取代 MySQL,而是要成为 MySQL 的“放大器”。其核心设计充满了对当时工程约束的精巧妥协:
无模式 (Schemaless):这并非真的没有模式,而是“读时模式”(schema-on-read)。数据以 JSON blob 的形式存储在 MySQL 的一个简单表中。这极大地简化了数据库端的管理,但也给应用层带来了数据解析和验证的负担。
仅追加 (Append-only) 与不可变性 (Immutability):为了简化系统设计和避免复杂的并发控制,
Schemaless的核心数据单元——Cell——被设计为不可变的。更新操作实际上是写入一个新的 Cell 版本。这使得系统非常健壮,但也让其难以用作通用数据库。二级索引:通过一个独立的索引系统,
Schemaless实现了对非主键字段的查询,这在当时是一个重要的创新。
Schemaless 成功地解决了 Uber 早期的规模化问题,证明了在成熟数据库之上构建抽象层的可行性。但它的“极简主义”设计,也为后来的演进埋下了伏笔。
Docstore 的演进——从 NoSQL 回归 SQL 的怀抱
随着时间的推移,Schemaless 的局限性日益凸显。其仅追加的 API 和“读时模式”对开发者不够友好,导致许多团队转向了当时流行的 Cassandra。然而,Cassandra 的最终一致性模型给应用开发者带来了巨大的心智负担,同时其运维复杂性和资源效率也未能满足 Uber 的严苛要求。
在亲身经历了 Schemaless 和 Cassandra 的优缺点后,Uber 团队做出了一个关键决策:将 Schemaless演进为一个通用的、支持事务的分布式 SQL 数据库。Docstore 就此诞生。

最低0.47元/天 解锁文章
223

被折叠的 条评论
为什么被折叠?



