使用Psycopg2在Python和PostgreSQL之间保持连续连接的最佳实践

2 投票
2 回答
1720 浏览
提问于 2025-04-15 15:58

我正在用Python和Postgresql 8.3写一个应用程序,这个程序在本地网络上的几台机器上运行。

所有机器都在做以下事情:

1) 从数据库服务器获取大量数据(比如说,一台机器在2秒内会向数据库发出100个不同的查询),而且大约有10到11台机器在同时进行这个操作。

2) 处理完数据后,机器需要更新某些表(每台机器每1.5秒大约有3到4个更新或插入的查询)。

我注意到,有时候数据库会崩溃,出现“服务器异常中止进程”这样的错误,或者服务器机器会卡住(需要强制重启)。

顺便提一下,所有机器在任何时候都保持与数据库的持续连接,也就是说,一旦通过Psycopg2(在Python中)建立了连接,它会一直保持活跃,直到处理完成(这可能需要几个小时)。

那么,处理大量连接的最佳或最优方法是什么?每次查询后应该断开连接吗?

其次,我应该增加最大连接数吗?

对此问题的任何建议我都非常感激。

2 个回答

1

这听起来像是你的数据库服务器可能有些问题,特别是如果你的数据库服务器真的崩溃了。我建议你先查看日志,找出问题的根本原因。可能是内存不够用,也可能是硬件出现了故障。

如果你一开始就打开了所有的连接并且一直保持这些连接打开,那么max_connections就不是问题所在。你处理数据库连接的方式应该没问题,不管服务器怎么配置,它都不应该出现这样的情况。

1

最可能的原因确实是内存不足。如果你使用的是Linux服务器,当内存用尽时,系统会启动一个叫做“OOM-killer”的机制,它会直接结束那些占用内存过多的进程(所以会出现“服务器异常终止进程”的情况)。内存不足通常意味着磁盘交换或分页的负担很重,这会让服务器看起来像是无响应。

你可以查看内核日志文件(或者使用dmesg命令)来找是否有类似“Out of Memory: Killed process 1234 (postgres)”的记录。这是因为系统默认允许内核“过度分配”内存。你首先应该做的就是禁用这种过度分配,以便更好地处理内存不足的情况:

echo 2 > /proc/sys/vm/overcommit_memory

方案A:

一个可能的原因是work_mem设置,它指定每个操作可以分配多少内存。一个查询可能包含多个需要大量内存的步骤,因此每个后端可以分配几倍于work_mem的内存,此外还有全局的shared_buffers设置。此外,你还需要一些空闲内存给操作系统的缓存。

想了解更多信息,可以查看PostgreSQL手册中的资源消耗设置:PostgreSQL 8.3 文档,资源消耗

方案B:

减少这些可调参数可能会让你的查询速度变得非常慢,导致仍然无法完成工作。一个替代方案是人为限制可以并行运行的查询数量。许多针对PostgreSQL的连接池中间件可以限制并行查询的数量,并提供排队功能。这类软件的例子有pgbouncer(更简单)和pgpool-II(更灵活)。

编辑:回答你的问题:

在应用中处理大量连接的最佳/最优方式是什么?查询后应该销毁连接吗?

一般来说,建立新的PostgreSQL连接速度并不快,因为PostgreSQL会为每个后端生成一个新的进程。不过,进程在内存方面的开销不小,所以保持很多空闲的数据库连接并不是个好主意。

我在方案B中提到的连接池中间件会负责保持合理数量的Postgres连接——无论你何时或多频繁地连接或断开连接。所以如果你选择这种方式,就不需要担心手动打开/关闭连接。

其次,我应该增加max_connections吗?

除非你的数据库服务器有大量内存(超过8GB),否则我建议不要超过默认的100个连接限制。

撰写回答