0

我们有一个 PostgreSQL 数据库来存储我们的 C++ 应用程序的数据,我们使用libpqxx连接到它。

pqxx::connection目前,我们为要运行的每个事务打开一个新事务。在部署中,我们预计每分钟最多执行大约四到五打事务,并且我们的应用程序将 24x7x365 运行。

根据 PostgreSQL架构基础

...[PostgreSQL 服务器进程] 为每个连接启动(“分叉”)一个新进程。

在我看来,我们pqxx::connection为每笔交易打开一个新进程的方法确实效率低下,因为我们每分钟间接产生几十个新进程。这是我们真的应该担心的事情吗?

在 PostgreSQL wiki 上看到 PostgreSQL 本身并不维护客户端连接进程池,所以看起来我们确实需要担心它。如果是这样,是否有一种“正确”的方法可以无限期地保留pqxx::connection对象,以便每次我需要连接到数据库时都不会派生一个新进程?请记住,我的应用程序需要每天运行一整天,因此我的 TCP 连接在很长一段时间后断开是不可接受的。

4

1 回答 1

3

您正在做的事情效率低下,但并非如此。PostgreSQL 的 fork 成本在 unix 平台上很低;创建和销毁后端相当便宜。

设置、身份验证等确实需要时间,因此您会增加交易延迟。

最好使用连接池,无论是在应用程序内还是在像 pgbouncer 这样的代理中。也就是说,对于“每分钟几十个连接”,除非您面临负载问题,否则我不会太担心。这很丑陋,但并没有那么糟糕。

不过,TCP 连接不会在一段时间后“掉线”。除非您在某些资源有限的状态 NAT 路由器或防火墙后面,否则它们可以无限期地保持空闲状态。如果你是你只需要启用 TCP keepalives。只要您愿意,就没有真正的理由不保持连接打开。

在任何情况下,您的应用程序应该已经具有连接丢失的重试逻辑,因为后端可能会由于管理操作、PostgreSQL 服务器崩溃恢复和重启、错误、导致 OOM 的服务器资源耗尽等而死掉。永远不要触发并忘记事务。您的应用程序应该记住从一开始就重做整个 xact 所需的完整状态,直到它收到 xact 已从数据库提交的确认。如果任何步骤出现故障,它应该能够重新连接并重试。

于 2016-04-28T17:01:40.167 回答