文章目录
-
- [一、Citus 是什么?](#一、Citus 是什么?)
-
- [1.1 定位与核心能力](#1.1 定位与核心能力)
- [1.2 适用场景](#1.2 适用场景)
- [二、Citus 架构原理](#二、Citus 架构原理)
-
- [2.1 节点角色](#2.1 节点角色)
- [2.2 数据分片(Sharding)机制](#2.2 数据分片(Sharding)机制)
- [2.3 查询执行流程](#2.3 查询执行流程)
- 三、安装与集群部署
-
- [3.1 安装方式(以 Ubuntu 为例)](#3.1 安装方式(以 Ubuntu 为例))
-
- [方法一:官方 APT 仓库(推荐)](#方法一:官方 APT 仓库(推荐))
- 方法二:Docker(开发测试)
- [3.2 初始化集群(3 节点示例)](#3.2 初始化集群(3 节点示例))
-
- [步骤 1:在所有节点安装 Citus + PostgreSQL](#步骤 1:在所有节点安装 Citus + PostgreSQL)
- [步骤 2:在 Coordinator 上启用 Citus](#步骤 2:在 Coordinator 上启用 Citus)
- [步骤 3:将 Worker 加入集群](#步骤 3:将 Worker 加入集群)
- [步骤 4:验证集群状态](#步骤 4:验证集群状态)
- 四、创建分布式表
-
- [4.1 分布式表类型](#4.1 分布式表类型)
- [4.2 创建分片表(Distributed Table)](#4.2 创建分片表(Distributed Table))
- [4.3 创建参考表(Reference Table)](#4.3 创建参考表(Reference Table))
- [4.4 分片策略选择建议](#4.4 分片策略选择建议)
- [五、SQL 兼容性与查询能力](#五、SQL 兼容性与查询能力)
-
- [5.1 完全支持的标准 SQL](#5.1 完全支持的标准 SQL)
- [5.2 分布式查询示例](#5.2 分布式查询示例)
-
- (1)单分片查询(高效)
- (2)多分片聚合(并行)
- [(3)分片表 JOIN 参考表(高效)](#(3)分片表 JOIN 参考表(高效))
- [(4)跨分片 JOIN(需重分布,性能较低)](#(4)跨分片 JOIN(需重分布,性能较低))
- [5.3 事务与一致性](#5.3 事务与一致性)
- 六、性能优化与调优
-
- [6.1 分片数量(Shard Count)](#6.1 分片数量(Shard Count))
- [6.2 写入优化](#6.2 写入优化)
- [6.3 查询优化](#6.3 查询优化)
- [6.4 资源隔离(企业版)](#6.4 资源隔离(企业版))
- 七、运维与高可用
-
- [7.1 扩容(Adding Nodes)](#7.1 扩容(Adding Nodes))
- [7.2 高可用方案](#7.2 高可用方案)
-
- [(1)Coordinator 高可用](#(1)Coordinator 高可用)
- [(2)Worker 高可用](#(2)Worker 高可用)
- [7.3 监控关键指标](#7.3 监控关键指标)
- 八、与生态工具集成
- 九、限制与注意事项
-
- [9.1 功能限制(截至 Citus 12)](#9.1 功能限制(截至 Citus 12))
- [9.2 性能陷阱](#9.2 性能陷阱)
- 十、典型应用场景详解
-
- [10.1 多租户 SaaS 平台](#10.1 多租户 SaaS 平台)
- [10.2 实时用户行为分析](#10.2 实时用户行为分析)
- [10.3 IoT 设备监控(与 TimescaleDB 结合)](#10.3 IoT 设备监控(与 TimescaleDB 结合))
- [十一、Citus vs 其他分布式方案](#十一、Citus vs 其他分布式方案)
PostgreSQL 本身是一个功能强大、稳定可靠的关系型数据库,但在面对 海量数据(TB/PB 级) 和 高并发写入/查询 场景时,单机架构会遇到性能瓶颈。为解决这一问题,Citus 应运而生------它是一个开源的 PostgreSQL 扩展,可将 PostgreSQL 集群化,实现 透明的水平分片(Sharding) 、分布式并行查询 、弹性扩展 与 高可用支持,从而构建高性能、可扩展的分布式数据库系统。
学习资源:
一、Citus 是什么?
1.1 定位与核心能力
Citus 是一个 PostgreSQL 的分布式数据库扩展 ,由微软(Microsoft)维护(原为独立公司,2019 年被收购)。它通过在多个 PostgreSQL 节点上 自动分片数据 ,并 并行执行查询,实现:
- 水平扩展:通过增加节点线性提升吞吐量
- 海量数据支持:轻松处理 TB 至 PB 级数据
- 高并发处理:支持数千 QPS 的复杂分析或实时查询
- 完全兼容 PostgreSQL:使用标准 SQL,支持 JSON、GIS、全文检索等所有 PG 特性
开源协议:AGPLv3(核心引擎),企业版提供额外功能
1.2 适用场景
- 多租户 SaaS 应用(按租户 ID 分片)
- 实时分析平台(如用户行为日志、IoT 数据)
- 高频交易系统(如支付、订单)
- 需要强一致性与 ACID 的分布式 OLTP/HTAP 混合负载
不适合:强跨分片 JOIN、频繁全局聚合(虽支持但有代价)
二、Citus 架构原理
2.1 节点角色
| 角色 | 说明 |
|---|---|
| Coordinator(协调器) | 接收客户端请求,解析 SQL,生成分布式执行计划,路由到 Worker 节点,汇总结果。不存业务数据(可选存元数据) |
| Worker(工作节点) | 存储实际分片数据(Shard),执行本地查询,返回结果给 Coordinator |
| (可选) HA 架构 | Coordinator 可配主备(通过流复制 + PgBouncer),Worker 节点支持分片副本(Citus 11+ 原生支持) |
注:Citus 11 起支持 无 Coordinator 模式(Direct Routing),应用可直连 Worker(需配合连接池),进一步降低延迟。
2.2 数据分片(Sharding)机制
- 分片键(Distribution Column) :用户指定某一列(如
tenant_id、user_id、event_time)作为分片依据 - 哈希分片 :对分片键值计算哈希,映射到固定数量的 Shard(分片)
- Shard 分布:每个 Shard 是一个标准 PostgreSQL 表,分布在不同 Worker 上
- 副本(Replication):每个 Shard 可配置多个副本(默认 1),实现高可用
示例:
sql
-- 按 user_id 分片,共 32 个分片
SELECT create_distributed_table('events', 'user_id');
→ 自动在各 Worker 上创建 events_10001、events_10002 ... 等分片表。
2.3 查询执行流程
- 客户端连接 Coordinator,发送 SQL
- Citus 解析 SQL,识别涉及的表是否为分布式表
- 若是:
- 根据 WHERE 条件中的分片键,路由到特定 Shard(Router Planning)
- 或 广播查询到所有 Shard(Broadcast)(如小表 JOIN)
- 或 重分布数据(Repartition Join)(跨分片 JOIN)
- 各 Worker 并行执行本地查询
- Coordinator 汇总结果,返回客户端
关键优化:避免跨节点数据移动,尽可能在本地完成计算。
三、安装与集群部署
3.1 安装方式(以 Ubuntu 为例)
方法一:官方 APT 仓库(推荐)
bash
# 添加仓库
curl https://install.citusdata.com/community/deb.sh | sudo bash
# 安装(匹配 PostgreSQL 版本)
sudo apt install postgresql-16-citus-12
方法二:Docker(开发测试)
bash
docker run -d --name citus-coordinator -p 5432:5432 citusdata/citus:12
docker run -d --name citus-worker1 citusdata/citus:12
docker run -d --name citus-worker2 citusdata/citus:12
# 需手动加入集群(见下文)
支持 PostgreSQL 12--16,Citus 版本需与 PG 匹配。
3.2 初始化集群(3 节点示例)
假设有 3 台机器:
coord: 192.168.1.10(Coordinator)worker1: 192.168.1.11worker2: 192.168.1.12
步骤 1:在所有节点安装 Citus + PostgreSQL
(略,同上)
步骤 2:在 Coordinator 上启用 Citus
sql
-- 连接 coord 节点
CREATE EXTENSION citus;
步骤 3:将 Worker 加入集群
sql
-- 在 coord 上执行
SELECT * from master_add_node('192.168.1.11', 5432);
SELECT * from master_add_node('192.168.1.12', 5432);
新版本(Citus ≥ 10)使用
SELECT citus_add_node(...),旧版用master_add_node。
步骤 4:验证集群状态
sql
SELECT * FROM citus_get_active_worker_nodes();
-- 应返回两个 worker 节点
四、创建分布式表
4.1 分布式表类型
| 类型 | 说明 | 适用场景 |
|---|---|---|
| Distributed Table(分片表) | 数据按分片键水平拆分 | 大事实表(events, orders) |
| Reference Table(参考表) | 全量复制到所有 Worker | 小维度表(users, products) |
| Local Table(本地表) | 仅存在于 Coordinator | 元数据、配置表 |
4.2 创建分片表(Distributed Table)
sql
-- 1. 创建普通表
CREATE TABLE events (
event_id BIGINT,
user_id INT,
event_time TIMESTAMPTZ,
payload JSONB
);
-- 2. 转换为分布式表(按 user_id 分片)
SELECT create_distributed_table('events', 'user_id');
默认创建 32 个分片(可通过
shard_count参数调整)。
4.3 创建参考表(Reference Table)
sql
CREATE TABLE users (
user_id INT PRIMARY KEY,
name TEXT
);
-- 复制到所有 Worker
SELECT create_reference_table('users');
优势:与分片表 JOIN 时无需网络传输,直接本地关联。
4.4 分片策略选择建议
| 分片键选择 | 优点 | 风险 |
|---|---|---|
| 租户 ID(多租户) | 数据隔离,查询高效 | 租户数据倾斜 |
| 用户 ID | 用户行为分析快 | 热点用户导致单分片压力大 |
| 时间戳(需谨慎) | 时间范围查询高效 | 写入集中到最新分片(热点) |
| 复合键(如 (tenant_id, user_id)) | 更均匀分布 | 查询需包含所有键才高效 |
最佳实践:选择高基数、查询高频、分布均匀的列作为分片键。
五、SQL 兼容性与查询能力
5.1 完全支持的标准 SQL
SELECT / INSERT / UPDATE / DELETEJOIN(包括分片表与参考表、分片表与分片表)GROUP BY,ORDER BY,LIMIT,WINDOW- CTE、子查询、事务(单分片事务强一致,跨分片最终一致)
5.2 分布式查询示例
(1)单分片查询(高效)
sql
-- user_id = 123 的数据只在一个分片
SELECT * FROM events WHERE user_id = 123;
(2)多分片聚合(并行)
sql
-- 所有分片并行计算 COUNT,Coordinator 汇总
SELECT COUNT(*) FROM events;
(3)分片表 JOIN 参考表(高效)
sql
SELECT e.event_time, u.name
FROM events e
JOIN users u ON e.user_id = u.user_id
WHERE e.user_id = 123; -- 可下推到单分片
(4)跨分片 JOIN(需重分布,性能较低)
sql
-- events 按 user_id 分片,logs 按 device_id 分片
SELECT * FROM events e JOIN logs l ON e.user_id = l.user_id;
-- Citus 会将 logs 数据按 user_id 重分布到 events 所在节点
优化建议:尽量让 JOIN 条件包含分片键,或使用参考表。
5.3 事务与一致性
- 单分片事务:完全 ACID,与 PostgreSQL 一致
- 跨分片事务 :通过 2PC(两阶段提交) 实现原子性,但:
- 性能开销大
- 不支持 SAVEPOINT
- 建议避免,或使用应用层补偿
六、性能优化与调优
6.1 分片数量(Shard Count)
- 默认 32,适用于中小集群
- 建议 :初始设为
Worker 节点数 × 2~4,未来可扩容 - 调整 :创建后不可直接修改,需通过
undistribute_table+ 重建
6.2 写入优化
- 批量插入 :使用
COPY或INSERT INTO ... VALUES (...), (...)(每批 1000~10000 行) - 避免随机分片键:导致写入分散,无法利用本地缓存
- 预分区(Pre-sharding):提前创建足够分片,避免后期 rebalance 压力
6.3 查询优化
- 强制路由查询:确保 WHERE 包含分片键
- 使用参考表代替小分片表
- 限制结果集 :
LIMIT尽早下推 - 监控慢查询 :
citus_stat_statements扩展(需启用)
6.4 资源隔离(企业版)
- 多租户资源组(Resource Groups):限制 CPU/内存/IOPS
- 查询优先级队列
七、运维与高可用
7.1 扩容(Adding Nodes)
sql
-- 添加新 Worker
SELECT citus_add_node('192.168.1.13', 5432);
-- 重新均衡分片(在线)
SELECT rebalance_table_shards('events');
rebalance_table_shards会自动迁移分片,保持负载均衡。
7.2 高可用方案
(1)Coordinator 高可用
- 使用 PgBouncer + 流复制主备 + VIP 切换
- 或应用直连 Worker(Citus 11+ Direct Routing)
(2)Worker 高可用
-
Citus 原生副本(Citus 11+) :
sqlSELECT alter_distributed_table('events', replication_factor => 2); -
或依赖 底层存储高可用(如云盘、ZFS、RAID)
7.3 监控关键指标
citus_shards:分片分布citus_lock_waits:分布式死锁pg_stat_statements:查询性能- Prometheus Exporter(社区提供)
八、与生态工具集成
| 工具 | 集成方式 |
|---|---|
| ORM(如 Django, SQLAlchemy) | 直接连接 Coordinator,像普通 PG 一样使用 |
| ETL 工具(如 Airflow, Talend) | 通过 psycopg2 驱动写入 |
| BI 工具(如 Metabase, Superset) | 连接 Coordinator 执行 SQL |
| Kafka Connect | 使用 JDBC Sink 写入 |
| TimescaleDB | 可在 Citus 分片表上启用 TimescaleDB(混合时序+分布式) |
注意:部分工具若依赖
information_schema,需确认兼容性。
九、限制与注意事项
9.1 功能限制(截至 Citus 12)
- 不支持 临时表
- 不支持 触发器(Triggers)(除部分简单场景)
- 不支持 外键跨分片引用
- 不支持 物化视图(但可建在本地表)
- 序列(SERIAL) 不保证全局唯一(建议用 UUID 或分布式 ID)
9.2 性能陷阱
- 跨分片 ORDER BY + LIMIT:需拉取所有分片 Top-N,再全局排序
- 大 OFFSET 分页:低效,建议用游标(cursor)或时间戳分页
- 全表扫描:即使有索引,若未带分片键,仍需扫描所有分片
十、典型应用场景详解
10.1 多租户 SaaS 平台
-
分片键 :
tenant_id -
优势 :
- 租户数据物理隔离
- 查询天然路由到单分片
- 扩容时按租户迁移
-
示例 :
sqlSELECT * FROM invoices WHERE tenant_id = 'acme' AND created_at > '2025-01-01';
10.2 实时用户行为分析
-
分片键 :
user_id -
结合 :
events(分片表) +users(参考表) -
查询 :
sqlSELECT u.name, COUNT(*) FROM events e JOIN users u ON e.user_id = u.user_id WHERE e.event_time > NOW() - INTERVAL '1 hour' GROUP BY u.name;
10.3 IoT 设备监控(与 TimescaleDB 结合)
- 在每个 Worker 上启用 TimescaleDB
- 分片键:
device_id - 每个分片是一个 Hypertable
- 实现 分布式时序数据库
十一、Citus vs 其他分布式方案
| 方案 | 优点 | 缺点 |
|---|---|---|
| Citus | 完全兼容 PG,SQL 丰富,易运维 | 跨分片事务弱,复杂 JOIN 性能差 |
| Vitess(MySQL) | 成熟于 YouTube,强分片 | 仅支持 MySQL,SQL 限制多 |
| TiDB | 强一致性,HTAP | 运维复杂,资源消耗大 |
| Greenplum | MPP 架构,分析强 | 写入弱,非 HTAP |
Citus 最适合 已有 PostgreSQL 技术栈 且需 平滑扩展 的团队。
总结:Citus 通过 扩展而非替换 的方式,将 PostgreSQL 升级为一个强大的分布式数据库。它保留了 PostgreSQL 的全部优势(SQL、JSON、GIS、可靠性),同时解决了单机扩展性瓶颈。
其核心价值在于:
- 透明分片:应用几乎无需改造
- 弹性伸缩:在线增删节点,自动 rebalance
- HTAP 能力:同时支持高并发 OLTP 与复杂分析
- 开源免费:核心功能完全开放
对于需要处理 海量数据、高并发、多租户或实时分析 的系统,Citus 是 PostgreSQL 生态中最成熟、最实用的分布式解决方案。