Citus 深度解读
“PostgreSQL 扩展的极简主义典范——不 fork 不魔改,做 PG 的插件而非替代品”
一句话定位
Citus 是作为 PostgreSQL 原生扩展(extension)运行的分布式查询引擎,通过 PG 的 hook 机制拦截查询处理流程,不 fork 不魔改,用最小的侵入实现 PostgreSQL 的水平扩展。
设计哲学上最精彩的地方
Citus 最精彩的决策是“做 PG 的插件而不是 PG 的替代品”。
想象你有一个非常好用的手机(PostgreSQL),Citus 不会让你换手机,它只是给你装了一个新 App——这个 App 让手机能同时控制多台设备协同工作。手机原来的所有功能完全不受影响,而且每次手机系统升级(PG 新版本),App 自动跟上。这意味着 Citus 的兼容性成本为零:PG 15 出来装上就能用,不用等 fork 跟进。
源码完美体现了这个理念。shared_library_init.c 是入口点,通过 PostgreSQL 的 hook 机制拦截查询处理。planner/distributed_planner.c 替换 standard_planner hook 介入查询优化;executor/adaptive_executor.c(5359 行,项目最复杂单文件)实现了连接池 + 任务调度系统,为每个 worker 节点维护 WorkerPool,通过 WaitEventSet 异步轮询 I/O。
五层渐进式查询规划:优雅的 fallback 设计
Citus 的分布式查询规划采用了五层逐级回退策略,命中即停:Fast-path Router(单分片快路径)、Router Planner(协同分片路由)、Modification Planning(DML 专用)、Recursive Planning(子查询递归)、Logical Planner(多关系代数树)。
planner/README.md 详细记录了每一层的设计动机和适用场景——这是开源世界最好的分布式查询规划器文档之一,学习分布式查询规划的最佳入门材料。
列存引擎:Table AM 接口的巧妙运用
src/backend/columnar/ 实现了一个完整的列式存储引擎,通过 PG 的 Table Access Method 接口注册。一条 ALTER TABLE 命令就能在行存和列存之间切换——ALTER TABLE ... USING columnar。这体现了 Citus 极致利用 PG 扩展机制的哲学。
局限性与场景边界
分布式事务支持比原生分布式数据库弱——依赖 2PC,不像 CockroachDB 那样有全局一致性保证。扩展模式意味着它受限于 PG 暴露的 hook 接口,某些底层优化做不了。单协调节点是潜在瓶颈,虽然可以配置多协调节点,但跨协调节点的元数据同步增加了复杂度。被 Microsoft 收购后,社区贡献活跃度不如独立开源项目。
本地代码结构
citusdata/citus (C)
src/backend/distributed/
shared_library_init.c # PG hook 入口点
planner/
distributed_planner.c # 分布式查询规划入口
README.md # 查询规划器最佳文档
executor/
adaptive_executor.c # 自适应执行器(5359行)
commands/ # DDL 命令处理
connection/ # Worker 连接管理
metadata/ # 分布式元数据管理
transaction/ # 分布式事务协调
src/backend/columnar/
columnar_tableam.c # 列存 Table AM 接口
columnar_reader.c # 列存读取
columnar_writer.c # 列存写入
columnar_compression.c # 列存压缩
本地关键文件
| 文件 | 用途 |
|---|---|
src/backend/distributed/shared_library_init.c |
PG hook 注册入口 |
src/backend/distributed/planner/distributed_planner.c |
分布式查询规划入口 |
src/backend/distributed/planner/README.md |
五层规划器设计文档 |
src/backend/distributed/executor/adaptive_executor.c |
自适应执行器(最复杂单文件) |
src/backend/columnar/columnar_tableam.c |
列存 Table AM 接口注册 |
src/backend/distributed/connection/remote_commands.c |
远程命令执行 |