PgDog:一个 Rust 代理把连接池、读写分离与自动分片全打包
阅读时间: 大约 9 分钟
PgDog:一个 Rust 代理把连接池、读写分离与自动分片全打包

PostgreSQL 水平扩展有两条老路:要么自己在应用层做分片,要么上 Vitess/Citus 这类重武器。「Koala 聊开源」介绍的 PgDog 走的是中间路线——一个用 Rust 写的代理,把连接池、查询负载均衡、整库分片三件事合进单一可执行文件,对外暴露一个端点。它管理逻辑复制与事务池化来实现水平扩展,官方称能在普通硬件上管数千连接。对从 PgBouncer 迁移过来的团队,其配置与端口(6432)都很熟悉。本文基于 pgdog.dev 与 GitHub 仓库做一次拆解。
一、背景:连接池器不够用了
PgBouncer 解决了「几千个客户端共享少量 Postgres 连接」的问题,但它不做分片、不做智能读写分离。当单库容量或写入吞吐到达上限,团队要么被迫重构应用层路由,要么引入重型分布式方案。PgDog 的切入点是:在「连接池代理」这个大家已经熟悉的位置上,直接叠加读副本负载均衡、故障检测、自动分片与 scatter/gather 查询,让应用像面对一个普通 Postgres 一样使用集群。
二、是什么
官方定位:「PostgreSQL 的连接池器、负载均衡器与分布式数据库,一个可执行文件,随处部署」。开源社区版采用 AGPL-3.0,另有企业版(EE)。它刚完成 550 万美元种子轮,GitHub 约 5K stars,生产中据称已承载 3M+ queries/s。
上手方式很轻:docker-compose 一键起带 3 个分片、2 张分片表的演示,再用 psql -h 127.0.0.1 -p 6432 连接(6432 正是 PgBouncer 的默认端口,刻意降低迁移成本)。配置只有两个文件:pgdog.toml(主机、分片设置)与 users.toml(账号密码)。
三、技术机制

从官网架构图看,请求路径是:应用(asyncpg/pgx/libpq/ruby-pg 等驱动)→ pgdog(pooler + load balancer + dsql 协调节点)→ 多个分片,每个分片由一个 primary 加若干只读副本组成。其能力分三层:
- 连接池(超越 PgBouncer):和 PgBouncer 一样支持事务级/会话级池化,让 10 万+客户端共享少量服务端连接;不同之处在于 PgDog 会解析 SET 语句与启动参数,正确维护会话状态,支持 advisory lock 与 LISTEN/NOTIFY,且不需要连接钉死(pinning)——这解决了 PgBouncer 事务池化下很多会话状态无法兼容的老问题;预处理语句对所有驱动兼容、零额外开销。
- 负载均衡与高可用:在副本间分发读请求,检测复制延迟与硬件故障,自动把写流量切到新 primary(无需改配置);通过内置的 Postgres SQL 解析器做读写分离——
SELECT走副本、其余走 primary;健康检查会把落后或损坏的副本摘流。 - 自动分片(dsql):协调节点直接从查询里解析分片键,把带键的请求路由到对应分片;不带分片键的查询则并行 scatter 到所有分片再聚合。OLTP 直路由快,OLAP 类的
GROUP BY / COUNT / AVG / ORDER BY / MIN/MAX / COPY开箱即用——官方称之为「Postgres + PgDog = scatter/gather 引擎」。
四、关键数据(官方口径)
| 指标 | 数值/内容 |
|---|---|
| 定位 | 连接池 + 负载均衡 + 自动分片,单二进制 |
| 实现语言 | Rust |
| 连接能力 | 10 万+客户端共享少量服务端连接 |
| 单线程吞吐 | 50,000+ 事务/秒/线程,无查询长度/连接数限制 |
| 生产规模 | 官方称 3M+ queries/s in production |
| 会话兼容 | SET、advisory lock、LISTEN/NOTIFY,不钉连接 |
| 高可用 | 副本延迟检测、故障摘流、primary 故障自动切流 |
| 分片 | 从查询解析分片键路由;无键查询 scatter/gather 并行 |
| 协议/版本 | 社区版 AGPL-3.0,另有企业版 |
| 融资/规模 | 550 万美元种子轮,约 5K GitHub Stars |
| 客户 | Coinbase、Ramp、Modal、Bitstack 等(官网) |
五、评测方法与口径批判
PgDog 官网给了不少数字,但要分层看:
- 「50,000+ 事务/秒/线程」与「3M+ queries/s」是官方自述,未给出基准硬件、网络条件与测试负载模型。前者是「每线程」上限,后者是客户生产总量,二者口径不同,不能直接相加或外推;
- 「不破坏 Postgres 特性」依赖它解析 SET/预处理语句,但解析器兼容性总有边界——复杂、非常规的会话用法或扩展行为仍可能踩坑,官方建议用前在测试环境验证;
- 「自动分片」是从查询里提取键,这意味着跨分片事务、不带键的复杂聚合会走 scatter/gather,延迟与放大效应需自行评估;它不是透明的无限水平扩展;
- AGPL-3.0 对云托管/SaaS 场景有传染性要求,商业闭源使用需走企业版——这是选型时的硬约束,不能忽略。
六、适用与不适用场景
适合:
- 已在用 PgBouncer、想要零学习成本升级到带读写分离+分片的团队;
- 单库到达容量/写入上限、希望按分片键水平拆分的 OLTP;
- 想要一个端点、自动处理副本延迟与主从切换的运维简化场景;
- 兼容 AGPL 或愿意购买企业版的开源团队。
不适合:
- 需要闭源/专有二次分发且不想买企业版的厂商(AGPL 限制);
- 分片键天然不明确、大量跨分片聚合的分析型负载;
- 想要完全托管、不愿自己运维分片拓扑的团队。
七、客观分析:优势与局限
优势:
- 三合一:连接池、读写分离、自动分片一个代理搞定,运维面小;
- 兼容 PgBouncer:端口/配置心智接近,迁移平滑,且补齐了会话状态兼容;
- Rust 高性能:单线程 5 万 TPS、异步多线程,资源占用低;
- 生产背书:Coinbase、Ramp 等已在生产使用,融资到位、持续维护。
局限:
- AGPL 协议:闭源/SaaS 商用受限,需企业版;
- 分片非透明:跨分片查询走 scatter/gather,有放大代价;
- 数字缺可复现基准:5 万 TPS/线程与 3M QPS 无公开测试条件;
- 解析器兼容性边界:非常规 Postgres 用法可能不被完美代理。
八、它意味着什么
PgDog 把「在 Postgres 前面加一层智能代理」这件事做到了较完整的程度:它不是让你换掉 Postgres,而是在你已经熟悉的连接池位置上,叠加读副本负载均衡、故障切换与按键自动分片。对被单库容量卡住、又不想上重型分布式数据库的团队,它是一条性价比很高的水平扩展路径——只是选型时务必把 AGPL 协议约束与跨分片查询代价一起算进去。