周三凌晨三点,手机报警又响了。一条简单的用户信息查询接口,响应时间从往日的4毫秒飙升到了4秒。匆忙登录服务器,PostgreSQL的CPU使用率低得可笑,慢查询日志干干净净,索引也没任何问题。你对着屏幕开始怀疑一切——代码没改过,流量也没暴涨,数据库像没事人一样,可用户那边已经超时一片。这不是数据库的故障,而是PgBouncer连接池被彻底耗尽了。在几乎所有重度使用Postgres的生产系统里,这类事故的发生频率远超慢查询,但误判率也高得离谱,很多人第一反应总是去查SQL、加索引,结果越绕越远。
下面就以一次典型的线上排查为线,把连接池耗尽这件事彻底拆开,不卖关子,直接上干货。
第一条:问题不在数据库,在“过路费”上。 PgBouncer作为连接池中间件,把成百上千的应用客户端映射到少量的物理数据库后端连接上,这本是一套优雅的省钱设计。可只要有任何因素让事务占用连接的时间超过预期——比如一次突然变慢的下游接口调用、等锁迟迟不释放、或者一个没有及时提交的游离事务——这套机制立刻从通道变成收费站。原本几十毫秒能完成的小查询,会因为前面积压的等待队列被拖成几秒,而且它们根本还轮不到进入Postgres,连执行计划都看不到。一旦看到客户端的等待数在涨、服务端活跃连接数死死顶在池子大小上限,就可以断定:池子满了,后面的所有请求都在排队,再快的查询也得乖乖等着。
第二条:池化模式选错,翻车率高到离谱。 多数团队在生产环境会选择事务池化模式,因为它让连接在事务提交的瞬间立即归还,用少量后台连接就能支撑海量客户端。听起来弹性十足,于是不少人把Postgres自身的连接数上限当作真正的瓶颈,完全不关心应用侧到底能同时维持多少个事务。真正的天花板不是Postgres的max_connections,而是你那套应用在同一时刻能保持多少未提交的事务。事务池化的另一面极其阴险:它让连接的释放看起来是自动的,于是任何需要在会话级别保持的东西——自定义搜索路径、预编译语句、临时表——都会变得极不稳定,出了问题定位起来很痛苦。至于最激进的语句级池化,直接打破了多语句事务的语义,基本只适合纯只读分析场景。而最保守的会话池化呢?一条客户端长连接死死绑定一个后端,池子有多大就只能接多少并发,稍微一压就满,属于把钱花得最不值的那种。
第三条:别凭感觉猜,两条命令直接照出病灶。 登录PgBouncer的管理端口,跑一句SHOW POOLS; 就能看到所有池子的实时状态。目光盯住两个数字:cl_waiting和sv_active。一旦等待客户端数在持续爬升,而活跃服务端连接数死死贴在池子配置的上限,铁证如山,所有后端槽位都被占满,客户端正排着长队。紧接着要做的就是跑到Postgres自身去查,到底是谁把那些槽位绑架了。十次里有八次,你会看到某个事务在等待一次跨网络的HTTP调用完成,或者在等一把从某次在线迁移遗留下来的锁。这种查找几乎不需要分析慢查询,纯粹的连接占用就能把整个系统卡死。
第四条:头号通缉犯——空闲事务泄露。 典型的反模式是这样:应用开启一个事务,做了一次读取,然后调了一个外部发货接口,等接口返回了才提交。在这整段等待时间里,那条数据库连接对于其他请求而言完全不可用,相当于占着茅坑不拉屎。在压力一上来的时候,单这一种写法造成的事故占比,远远超过任何流量峰值。ORM框架里这种行为尤其容易隐蔽,很多人甚至意识不到某段代码已经处在事务上下文中。所以排查时请盯紧pg_stat_activity里状态为idle in transaction的连接,超过几秒的大概率就是祸首。别幻想这是数据库的优化问题,这就是代码行为问题。
第五条:调池子大小别拍脑袋,用利特尔法则打底。 一个很实诚的估算公式:需要的连接数 = 请求到达率 × 平均事务耗时。但它最要命的坑在于,你要按尾部延迟来算,而不是平均值。一次慢查询或者一次突然的网络重试,就能让整个估算扭曲得不成样子。所以不要一看到等待就把池子开大,更多后端连接意味着更大的内存开销和更强的锁竞争,完全不是免费的午餐。合理的策略是先通过应用侧的改造消除不必要的空闲事务,再结合事务耗时分布去定池子大小,最后留出足够的余量应付流量毛刺。再往上堆连接数,就像给一个漏水的桶拼命加水,治标不治本。
下一次你看见数据库CPU闲得很、可用户端却在超时的时候,不要再去翻慢查询日志了。先看一眼PgBouncer的池子状态,大概率会发现,数据库什么事也没有,全是连接调度在背锅。把诊断顺序改过来,处理这类事故的时间能缩到原来的十分之一。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.