pgbouncer
是最广泛使用的连接池工具之一。在 CYBERTEC,我们已经在许多不同的情况下成功地部署了它。它已被证明是可靠且有用的。
在我们深入研究不同的池模式及其含义之前,为什么我们首先需要一个连接池?原因是我们想减少新连接的开销。没错。创建新连接不是免费的。
通过连接池减少连接开销
如前所述,连接及其创建不是免费的。在 PostgreSQL 中,我们必须分叉整个过程来创建连接。如果连接存在很长时间,这没有问题。然而,只为一个非常短的查询分叉一个进程可能非常昂贵。开发人员和 DBA 一样经常低估这些成本。
让我们使用一个简单的脚本运行一个测试:
|
为了最大化结果,我使用了最基本的脚本。
让我们运行一个简单的测试:给定我们的 SQL 脚本,10 秒,10 个并发事务。测试硬件:Mac Mini (M1)。
|
这给了我们每秒 295825 个事务。但现在让我们再次运行相同的测试。这一次,每个事务都会打开一个单独的连接(-C
):
|
哇,我们将速度降低到每秒 3770 个事务,性能下降了 98.7%。
如果您考虑一下,这是合乎逻辑的。“ SELECT 1
”比fork()
加上所有其他开销要便宜得多。因此池化很有意义,因为它允许我们回收连接。
pgbouncer:连接池的最佳工具
pgbouncer
可以进入图片解决问题。这里的关键是一个pgbouncer
连接只有 2 Kb 左右的开销。换句话说,它真的很高效,它可以以很少的开销容纳数千个连接。当然,会有更多的延迟——但总的来说,它有助于大大减少打开和关闭连接的需要。
典型设置如下所示:
pgbouncer
将位于数据库和客户端之间。它将保持与数据库的连接打开,并确保fork()
所需的调用次数显着减少。
连接池模式的类型
pgbouncer
具有三种池化模式。理解这一点很重要,因为它提供了很大的潜力来调整工具的行为以满足我们的确切需求。
配置文件显示以下选项:
1 2 3 4 5 |
|
所有这些选项是什么意思?让我们详细讨论一下。
pgbouncer 会话池
会话池意味着pgbouncer
保持一组与服务器的连接处于打开状态。客户端将选择一个,然后将事物路由到数据库。
也可以用来pgpool
“缩小”数据库端真正需要的连接数。如果您有一些疯狂的应用程序端连接池需要异常大量的打开连接,而这些连接池一开始就不应该连接到后端数据库,这可能会很有用。
如果所有连接都正常工作,其中一些必须等到池中的插槽可用。通常许多使用连接池的应用程序访问同一个数据库。许多运行过大池的应用程序最终可能会导致后端连接过多——这反过来又会导致问题。
每个客户端都将在同一个“真实”数据库连接上运行整个事务甚至整个连接。
pgbouncer 事务池
有时完全连接太多了。那么事务池呢?与其将整个客户端连接映射到真实的数据库连接,不如确保相同的事务最终在同一台主机上结束就足够了。
pgbouncer
因此会将许多客户端连接映射到同一个物理连接并通过事务将它们分开。通常这完全足够了。
pgbouncer 语句池
语句池是迄今为止最激进的方法。通常你不需要大的交易块。假设您希望每秒在电话簿中查找姓名 100 万次。显然,这些都是快速、小型的查询,并且没有跨越多个语句的大型事务。因此,我们不必担心事务可见性。我们可以简单地将所有这些语句负载平衡到任何连接并将结果传递给客户端。
用例如下: 通过系统泵送数百万条短语句,这些语句与需要重锁(例如 SELECT FOR UPDATE)或其他任何类型的大型花哨业务逻辑无关。
最后 …
根据您的需要,您可以决定要使用的池化方法。通常使用会话池,但我们也看到了大规模的语句池。
原文标题:PGBOUNCER: TYPES OF POSTGRESQL CONNECTION POOLING
原文作者:Hans-Jürgen Schönig
原文链接:https://www.cybertec-postgresql.com/en/pgbouncer-types-of-postgresql-connection-pooling/