我正在使用 Postgresql 8.3 在 Python 中编写一个应用程序,它在本地网络上的多台机器上运行。
所有机器
1) 从数据库服务器获取大量数据(假设数据库在 2 秒内从一台机器获取 100 个不同的查询)并且大约有 10 或 11 台机器在做这件事。
2) 处理数据后机器必须更新某些表(每台机器每 1.5 秒大约 3 或 4 个更新/插入查询)。
我注意到,数据库有时会因服务器异常中止进程或卡住服务器机器(需要硬重置)而宕机。
顺便说一下,所有机器始终保持与数据库的持续连接,即一旦使用 Psycopg2(在 Python 中)建立连接,它就会保持事件状态,直到处理完成(可能持续数小时)。
在应用程序中处理大量连接的最佳/最佳方式是什么,是否应该在每次查询后销毁它们?
其次,我应该增加 max_connections 吗?
非常感谢有关此事的任何建议。
最佳答案
最可能的原因确实听起来像是内存不足。如果这些是 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 Documentation, Resource Consumption
B 计划:
减少这些可调参数可能会大大降低您的查询速度,以至于您仍然无法完成任何工作。另一种方法是人为地限制可以并行运行的查询数量。许多用于 PostgreSQL 的连接池中间件可以限制并行查询的数量,并改为提供排队。此软件的示例是 pgbouncer (更简单)和 pgpool-II (更灵活)。
编辑:回答您的问题:
What's the best / optimal way for handling large number of connections in the application, should they be destroyed after each query ?
一般来说,与 PostgreSQL 建立新连接的速度并不快,因为 PostgreSQL 会为每个后端生成一个新的进程。但是,进程在内存方面并不便宜,因此保留许多与数据库的空闲连接并不是一个好主意。
我在B 计划 中提到的连接池中间件将负责保持与 Postgres 的合理数量的连接——无论您何时或以何种频率与池连接或断开连接。因此,如果您选择该路线,则无需担心手动打开/关闭连接。
Secondly should I increase max_connections ?
除非您的数据库服务器有大量 RAM(超过 8GB),否则我不会超过 100 个连接的默认限制。
关于python - 使用 Psycopg2 保持 Python 和 Postgresql 之间持续连接的最佳/最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1728350/