Postgres如何处理超过连接数上限的高并发请求
Postgres 高并发连接场景问题解答
1万并发请求抵达默认配置Postgres的实际表现
Postgres 默认max_connections参数值为500,其中会预留3个连接专门给超级用户做运维操作,普通业务实际可用的连接只有497个:
- 前497个普通请求可以正常建立连接,执行对应的查询操作
- 剩余的9503个请求会直接收到连接拒绝报错,错误信息为
FATAL: too many connections already,完全无法执行任何数据库操作
请求与连接数上限的匹配逻辑
Postgres 采用每连接对应一个独立后端进程的架构,本身没有内置的请求排队、连接复用机制:
- 所有请求到达后会直接尝试申请连接资源,没有空闲连接就直接拒绝,不会默认进入等待队列
- 如果需要实现请求排队、连接复用能力,需要额外部署连接池组件(比如Pgbouncer),由连接池管控连接分配,空闲连接会被回收给后续请求复用,超出连接池配额的请求才会进入队列等待,不会直接打到数据库层面。
高并发场景的方案选择
不要盲目直接调高max_connections参数,优先按以下优先级判断适配方案:
- 首选方案:部署服务端连接池。90%以上的高并发连接场景都是因为业务端没有做连接复用,大量短连接、空闲连接占满了连接配额。正常来说,4核8G规格的Postgres实例,活跃连接数控制在100~200就能打满CPU资源,更高的连接数只会增加进程上下文切换开销,反而降低整体吞吐量。
- 次选方案:如果业务确实存在大量不可压缩的慢查询,或者连接池优化后活跃连接数仍然长期打满,再考虑调整
max_connections,调整的同时需要同步调高操作系统的max_files_per_process等内核参数,避免出现资源不足报错,调整后的最高值不要超过2000。 - 最终方案:如果单实例连接数已经到瓶颈,且CPU、内存、IO资源长期跑满,再考虑新增Postgres实例做水平分库、读写分离,分摊请求压力。
不要指望数据库自身的并发机制处理超10倍连接上限的请求,Postgres自身没有内置连接排队能力,超配请求只会直接被拒绝。
内容的提问来源于stack exchange,提问作者Saurabh_Jhingan
相关产品推荐
相关产品推荐

