PostgreSQL Connection Poolers

数据库连接池(Connection Pooler)是一种用于管理和复用数据库连接的组件,它允许应用程序在需要与数据库建立连接时从连接池中获取连接,而非每次都创建新的连接,以减少连接创建和销毁的开销。今天我们介绍 PostgreSQL 数据库生态中常用的四个具有连接池能力的工具: PgBouncer、Pgpool-II、Odyssey、PgCat。 为什么需要连接池? 通常 DBA 会给 PostgreSQL 实例设置一个合理的 max_connections 值,当连接数超过这个值后会报 FATAL: remaining connection slots are reserved for ... 的错误。 有些人认为 PostgreSQL 不能处理太多连接是因为它的进程模型(为每个连接创建一个 backend 进程)会占用大量内存,但其实更重要的原因是 Snapshot scalability,当有大量连接(即使状态为 idle)时,获取快照信息(GetSnapshotData)成为了性能瓶颈。 PG 14 针对 Snapshot scalability 的问题进行了优化: Improving Postgres Connection Scalability: Snapshots,降低了 idle 状态连接对数据库性能的影响,因此我们现在可以把 max_connections 设置为一个较大的值(maybe 1000~5000?)。那这是否意味着我们不再需要连接池了?答案是否定的,我能想到的两个原因: 应用端大量的短连接频繁创建、删除有性能开销 微服务架构下存在大量应用,相对单体架构需要更多的连接,连接数依然可能耗尽 依据连接池运行的位置可简单将其分为两类,一种是存在于应用程序的 driver 里,如 pgjdbc-ng 库提供的 Connection Pool DataSource;另一种是单独部署的进程。后文介绍的四个连接池都归为第二类。 PgBouncer PgBouncer 是一款轻量的连接池解决方案,单线程、低开销(单个连接占用约 2kB 内存)、使用 libevent 事件驱动库来处理异步 I/O,功能简单,配置容易。 三种使用模式: 会话模式(Session pooling): 一个客户连接对应一个服务端连接,支持 PostgreSQL 所有特性,常用于多个数据库的连接映射(Connection Mapping) 事务模式(Transaction pooling): 一个服务器连接只在事务期间分配给客户端。当 PgBouncer 察觉到事务结束时,连接将被放回连接池中。这种模式会破坏几个基于会话的功能 语句模式(Statement pooling): 不允许多语句事务,意味着 autocommit 必须打开 事务模式不支持的特性有:...

November 5, 2023 · 3 min · 512 words · pg-x