Lobsters | 📄 原文链接 | 2026-11-08 收录

Postgres 当任务队列在哪里崩:1 核 64 个 worker 就撞墙

来源:garbagecollected.io — 2026-11

📋 概述

一篇实测文章,问的是「Postgres 队列到底在哪一步撑不住」。设计是社区最常见的 FOR UPDATE SKIP LOCKED:jobs 表带 payload、status、run_at、locked_at、finished_at,加一个 WHERE status = pending 的部分索引;worker 用一条 UPDATE 认领一行、干 100ms 活、再用一条 UPDATE 标完成。环境是 docker 里限 1 CPU、1GB 内存的 Postgres 18,shared_buffers 256MB,默认 max_connections = 100;worker 从 1 一路翻倍到 128,每轮前重灌 50 万条待办并 VACUUM ANALYZE、CHECKPOINT。结果:吞吐涨到 32 worker 的 292 个/秒后,在 64 worker 处停在 376 个/秒,128 worker 反而掉到 208 个/秒并且 29 个连不上。卡住的不是连接数而是 CPU——64 worker 时已 86%,128 时 100%;内存只用掉 560MB/1GB。等待事件也印证:64 worker 时最常见的是 LWLock:WALWrite(每个任务两次写 WAL),128 时变成 LWLock:BufferContent,24 个连接同时抢队首页的那几页。加上 20 条连接的客户端池后,128 worker 跑到 652 个/秒、p99 从 1.6 秒降到 360 毫秒,但 CPU 仍在 98%——连接池把天花板往后推,而不是取消它;而且此时客户端 Python 进程自己也吃掉一整核。

🔑 核心要点

💡 金句

在只给 1 个 CPU 的 Postgres 上,64 个 worker 时队列吞吐峰值约 375 个任务/秒——CPU 在 100 个连接槽用完之前就先耗尽了。
← 返回 Lobsters 首页