PROD欧洲主权BaaS平台打开仪表板 →

性能 · 11 最小读取值

PgBouncer vs Supavisor vs PgCat:哪个 Postgres 池化器?

Affane Daylami · Fondateur · 2026年6月9日

返回博客

PgBouncer、Supavisor 和 PgCat 都共享 Postgres 连接,但它们没有解决相同的问题。 PgBouncer 仍然是历史标准:轻量级、C 语言、通过 CloudNativePG 原生集成到 Kubernetes 生态系统中。 Supavisor 是 Supabase 为满足特定需求而构建的,旨在通过一项服务支持数千个数据库,而不是每个数据库一个进程。 PgCat 用 Rust 编写,添加了经典的分片池和副本之间的负载平衡。在 Aurabase,数据平面流量以事务模式通过 PgBouncer。这直接显示在存储库代码中:Helm 图表、CNPG Pooler 资源和本地 k3d 配置都趋向于相同的选择。

该英文文本是根据法文原文自动生成的,尚未经过审查。
该页面已自动翻译。英文版具有权威性。

本文比较了三种池化器的架构:语言、池化模式、单租户或多租户模型、纯池化之外的功能。 Tembo 和 PkgPulse 已经发布了这三种工具的数值比较,但我们自己还没有复制它们的任何测量结果。我们对基准的编辑立场(在我们的 基准方法中详细说明)是,永远不要重新发布未经我们自己验证的数据。您将在这里找到:每个工具的实际架构,以及 Aurabase 如何实际路由其 Postgres 流量,在源代码中逐节进行验证。

要点
  • PgBouncer (C) 仍然是最成熟的池化器,并且与 Kubernetes 集成得最好:CloudNativePG 直接依赖它的 Pooler资源。
  • Supavisor(Elixir、Supabase 项目)针对的是一个不同的问题:通过同一服务为数千个数据库提供服务,而不是每个数据库一个池化器。
  • PgCat (Rust) 添加了应用程序分片、副本之间的负载平衡以及原始池的自动故障转移。
  • Aurabase 存储库显示 PgBouncer 在两个级别上使用:共享队列的共享部署,以及由每个专用租户的 CloudNativePG 管理的 Pooler 资源。两者都以事务模式运行。
  • PostgREST 和aura-db 管理池自愿保持与 Postgres 的直接连接,而不通过池程序:事务池会破坏它们的模式重新加载和会话锁。
#
全景

三个池子,三种哲学

PgBouncer 最小化,Supavisor 池在多租户规模上,PgCat 在原始池中添加网络功能。尽管这三者经常在同一页面上逐个术语进行比较,但它们都不是其他两者的直接替代品。

语言C长生不老药(光束)铁锈
池化模式会话、交易、声明会话、交易会话、交易、声明
租赁模式每个实例一个目标集群,设计为单租户原生多租户:为多个数据库提供服务目标集群,按分区键分片
超越池化没有额外的功能,故意最小化管理 HTTP API,动态租户注册副本之间的分片、负载平衡和故障转移
原生 Kubernetes 集成是:CloudNativePG 资源池迄今为止尚未有本地记录迄今为止尚未有本地记录
产地Postgres池化的历史标准由 Supabase 为其自己的多租户云构建诞生于 Instacart,如今由 PostgresML 维护

列,按顺序:PgBouncer、Supavisor、PgCat。根据每个项目的官方文件的架构特征,将在您正在部署的版本上进行确认,生态系统在这一点上正在快速发展。

#
保镖

历史性标准,轻量级并集成到 Kubernetes 中

PgBouncer 只做一件事:池 Postgres 连接,没有任何附加功能。这种故意缩小的范围在很大程度上解释了它的长寿以及它在大多数生产中的 Postgres 堆栈中作为基本构建块的采用。

Three pooling modes are available. Session mode opens one server connection per client connection, the most permissive. Transaction mode reuses a server connection between several clients, released at each end of a transaction. Statement mode goes even further, and is rarely used in production. It is the transaction mode that brings the real pooling gain, but it imposes strict rules. Any session state (SETvariables, advisory locks, LISTEN/NOTIFY) does not survive beyond a transaction. We detail these rules and their pitfalls in our dedicated article on the transaction pooling mode of PgBouncer.

历史上,PgBouncer 实例是单进程的,默认情况下使用单个 CPU 核心。在同一端口后面运行多个实例(通过 SO_REUSEPORT)是该项目的最新演变,而不是最初的设计功能。在身份验证方面,PgBouncer 支持可配置的 auth_query,这是一个在每个连接上执行的 SQL 函数,用于动态解析角色的密码。这种机制避免了依赖于预先列出每个用户的静态文件。 Aurabase 正是将这种机制用于其每个项目的角色(第 05 节)。

阿斯图塞

PgBouncer 是 CloudNativePG 在其 Pooler资源后面本地部署的池化器。在由 CloudNativePG 操作员管理的 Postgres 集群上,激活托管池程序实际上相当于激活 PgBouncer,而无需手动配置它。

#
监督者

Supabase 的云原生多租户池化器

Supavisor 解决了 PgBouncer 从未设计用于解决如此规模的问题。这涉及从一项服务提供大量不同的租户数据库,而不是每个数据库一个池化器实例。该项目用 Elixir 编写并在 Erlang 虚拟机 (BEAM) 上执行,由 Supabase 在其自己的 GitHub 存储库上开源开发和维护。

原生多租户模型才是真正的结构差异。经典的 PgBouncer 队列需要每个目标基地一个进程(或一组专用连接),而 Supavisor 的工作方式有所不同。它通过 HTTP 管理界面动态注册租户,并将每个传入连接路由到正确的数据库,而无需重新启动服务。正是出于这个原因,Supabase 将自己的云项目从 PgBouncer 迁移到了 Supavisor。每个数据库一个的经典池集群无法扩展到托管数十万个项目的多租户云。

这种架构选择有一个已记录的缺点。项目启动后,在高级案例上与 PgBouncer 的功能对等需要一段时间才能稳定下来。两个例子: LISTEN/NOTIFY的某些行为,以及事务模式下准备语句的精细管理。如果您的应用程序依赖于这些特定行为,请在迁移前检查您的版本。

#
PG猫

Rust 局外人:原生分片和负载平衡

PgCat 被明确定位为 PgBouncer 的替代品,用 Rust 编写。它向经典池化添加了 PgBouncer 和 Supavisor 本身均未嵌入的网络功能。特别是三个:按分区键的应用程序分片、只读副本之间的负载平衡以及从故障副本自动进行故障转移。该项目诞生于 Instacart,如今由 PostgresML 接管和维护。

具体来说,PgCat 可以扮演两个不同层通常占据的角色:连接池和用于在多个 Postgres 实例之间路由的应用程序代理。已经手动分片数据的团队可以使用 PgCat 简化其代码。对于内部开发的在副本之间分配读取的逻辑也是如此:专用网络层直接取代它。

相反的妥协也存在:PgCat 是一个较年轻的项目,与 PgBouncer 相比,文档和生产反馈的生态系统要小得多。采用其分片和故障转移功能还意味着同意依赖该特定组件的成熟度,而不仅仅是其池容量。

#
已签入代码

Aurabase 代码显示的内容:PgBouncer 无处不在,除了事务池破坏一切的地方

Aurabase 存储库在两个不同的层部署 PgBouncer,均采用事务模式。对于共享队列,Helm 图表在共享数据平面(deploy/helm/aurabase/templates/infra/pgbouncer.yaml,图像 edoburu/pgbouncer)前面定义了专用的 PgBouncer 部署。对于专用实例上的租户,配置程序会生成由 CloudNativePG 本机管理的资源 Pooler (deploy/cnpg/tenant-pooler.yaml,由 k8s_tenant.rs呈现)。两者都不使用 Supavisor 或 PgCat。该代码没有记录此选择之前的显式比较。另一方面,它显示了与 CloudNativePG 生态系统的深度且已经可操作的集成,这与 PgBouncer 是本机池砖的事实一致。

交易
池化模式
由专门租户共享车队和池
1000
最大客户连接
同时客户上限,Helm图表默认
80
默认池大小
按(基础、角色)划分的服务器连接,默认 Helm 图表

然而,并非所有内容都经过池化器,这是代码本身中记录的有意选择。 PostgREST 仍然与 Postgres 保持实时连接,而不是通过 PgBouncer。 Helm 图表注释明确说明了原因:事务池会破坏其模式重新加载,这取决于 pgrst通道上的 LISTEN 。此机制与客户端之间回收的服务器连接不兼容。出于相同的基本原因,aura-db 管理池(架构、DDL、会话咨询锁)也保持直接连接。非事务范围的 SET search_path 和会话锁在事务模式池化器中无法生存。

deploy/helm/aurabase/templates/infra/pgbouncer.yaml (extrait commenté)yaml
# 数据平面 aura-db:通过 PgBouncer,一切都是事务范围的(SET LOCAL)
DATABASE_URL: postgresql://aura_authenticator:...@pgbouncer:5432/aura_db_master

# 池管理(DDL、内省):直接在 Postgres 上,从不 PgBouncer
# SET search_path 非 LOCAL + 会话锁会破坏事务池
ADMIN_DATABASE_URL: postgresql://aura:...@postgres:5432/aura_db_master

身份验证遵循第 02 节: AUTH_QUERY: SELECT * FROM pgbouncer.user_lookup($1)中描述的 auth_query 模式,没有静态 userlist.txt 文件。这使得每个项目 (project_<uuid>_authenticator) 动态创建的角色可以通过 PgBouncer 进行身份验证,而无需为每个新项目重新部署池化器。

写这篇文章时发现的一个操作教训

本地 Kubernetes 清单中的 PgBouncer healthcheck 注释记录了一个真正的错误,并且已经修复。针对 PgBouncer 运行的 pg_isready 仅验证代理握手,而不会验证与其中继的 Postgres 后端的实际连接。即使后端停止,PgBouncer 也会响应“接受连接”,对请求进行排队。在破坏性测试中观察到的结果:服务连续 5 个周期保持 healthy,而 Postgres 无法访问。该修复通过池化器将检查替换为真正的端到端 psql 请求,一直到后端。校正后的结果,在同一测试中重播:unhealthy 在 7 个周期中检测到,大约 35 秒。

最后一个细节,虽小但很有启发性:Helm 图表默认引脚 edoburu/pgbouncer:v1.24.1-p1 ,而本地 k3d 工作台使用 v1.25.2-p0。这不是一个架构选择,只是两个环境之间稍微缺乏版本同步,代码审查比博客文章捕捉到的细节更快。我们按原样记录它,而不是修饰它。有关此池程序所服务的架构分区的详细信息,请参阅我们关于多租户 RLS 隔离的文章。

#
决定

三者如何选择

如果...选择 PgBouncer

  • Postgres 集群通常由 CloudNativePG 或 Kubernetes 管理
  • 您想要最经过验证和记录最齐全的池化器
  • 每个池化器实例的目标基数适合您

如果……选择督导员

  • 同一服务背后有数百或数千个基地
  • 需要通过 API 动态注册租户,无需重新部署
  • 已经在 Supabase 生态系统中或愿意依赖它

如果...选择 PgCat

  • 应用程序共享已经到位或计划在池级别
  • 负载平衡和故障转移副本,无需单独的应用程序层
  • 能够适应较年轻的项目,但文档比 PgBouncer 少

无论选择什么池化器,它都不会取代 Postgres 本身的大小。池大小和服务器 max_connections 应该一起考虑,而不是一个接一个。太低的 max_connections 前面的宽敞池只会将饱和度从一个级别转移到另一个级别。我们关于 调整 max_connections 的指南详细介绍了在设置池大小之前要应用的大小调整公式。

#
常见问题

我们最常被问到的问题

PgBouncer 和 Pgpool-II 有什么区别?+
Pgpool-II 超越了连接池:副本之间的负载分配、内存中查询缓存、应用程序复制。 PgBouncer 只做一件事:池连接。这在一定程度上解释了为什么它经常被选为基本构建块,并在必要时辅以其他工具,而不是被更广泛的平台取代。
我们可以将 PgBouncer 与 Supabase 一起使用吗?+
历史上是的:Supabase 在开发 Supavisor 之前依赖于 PgBouncer。两者都根据连接上下文保留在其官方文档中:IPv4 直接、池化器事务、池化器会话。这个精确点发展很快,可以在配置项目时进行检查。
PgCat 是否以事务模式管理准备好的语句?+
自版本 1.21 起,PgBouncer 在事务模式下动态跟踪并重新准备协议准备好的语句,这种行为记录在 Aurabase Helm 图表本身中。 PgCat 声称提供类似的服务器端支持。我们尚未在实际负载条件下测量其中任何一个,因此请先检查您自己的流量,然后再将其作为决定性的选择标准。
Supavisor 是开源的吗?+
是的,该存储库在 GitHub (supabase/supavisor) 上是公开的。这是一个与 Supabase 的 Postgres 核心不同的项目,它是用 Elixir 编写的,从一开始就为多租户设计,而不是事后进行调整。
#
综上所述

没有万能的共用器,只有适合您的租赁的

PgBouncer、Supavisor 和 PgCat 解决同一问题的三个变体,而不是同一工具的三个版本。当您的平台已经依赖 Kubernetes 和 CloudNativePG,或者您只是想要文档最多的池化器时,PgBouncer 仍然是最安全的选择。 Supavisor 的相关性超过了通过同一服务提供服务的一定数量的基地。如果您错过了网络级别的分片和副本故障转移,并且您接受了较年轻项目的成熟度,那么 PgCat 值得绕道而行。

Aurabase 代码显示了一致的而非中立的选择:交易模式下的 PgBouncer,有两个级别:共享队列和每个专用租户的 CNPG 池化器。对于 PostgREST 和模式管理,仍然存在两个已记录的例外情况。如果您想看到这个项目的实际运作而不是纸面上的情况,我们的 性能 页面记录了相关的测量方法。

准备好部署了吗?

五分钟内完成您的后端。

无需信用卡 · 500 MB 免费 · 50,000 MAU