从0到1.5亿QPS:Uber核心存储架构的十年演进与缓存设计哲学

大家好,我是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 就此诞生。

设计哲学:两全其美

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值