在不使用微服务的情况下扩展 PostgreSQL:来自 Notion 的 480 个分片的经验教训

发布: (2026年2月21日 GMT+8 14:03)
3 分钟阅读
原文: Dev.to

Source: Dev.to

TL;DR: Scaling Notion’s Monolith

  • Application‑Level Sharding – 480 个逻辑分片映射到更少的物理节点。
  • Shard Router – 使用 TypeScript 实现,利用 space_id % 480 即时路由请求。
  • PgBouncer – 充当流量控制器,池化连接以防止过载。
  • Zero‑Downtime Migrations – “Shadow Write” 策略在保持应用在线的同时迁移数十亿行数据。

Chapter 1: The Problem with Monolith

在 Notion 的早期架构中,Node.js 后端配合单个 PostgreSQL 实例。随着时间推移,他们遇到了:

  • CPU Saturation – 日常峰值经常超过 90 % 的利用率。
  • The Vacuum Problem – Autovacuum 无法跟上,存在事务 ID 回绕的风险,回绕会为了保护数据完整性而停止写入。

Chapter 2: Why Not Microservices?

典型的微服务论点是“拆分代码,拆分负载”。Notion 走了一条不同的道路,保持单体代码库的同时对数据层进行扩展。

Chapter 3: The 480‑Shard Blueprint

Logical Shards

  • Partition Key – 使用 space_id 作为分区键,使得同一工作区的所有数据保持在一起,便于快速关联。
  • Setup – 480 个独立的 schema(逻辑分片)分布在 32 台物理 AWS RDS 实例上。

Benefits

  • 当某台服务器负载过高时,可以将一个逻辑 schema 移动到新服务器,实现线性可扩展性。

Chapter 4: The Great “Shadow” Migration

Backfill

  • 将历史数据在后台迁移到新分片。

Double Writing

  • 新的更改同时写入旧数据库和新分片。

Cutover

  • 在比较引擎验证数据一致性后,将流量切换到新分片,实现零停机。

Future Improvements

  • Scaling to 96 Nodes – 将物理节点数量扩展到 96 台,以进一步分散负载。
  • Blocks All the Way Down – 继续把每一块内容都视为 block,实现细粒度分片。
  • Data Lakes & Connection Hubs – 探索集中式分析和集成点。

Feel free to share your thoughts in the comments!

0 浏览
Back to Blog

相关文章

阅读更多 »