跳到主要内容

数据库连接池:AI 流水线中被忽视的性能瓶颈

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 AI 功能上线了。在预发环境中,响应时间看起来还不错。一周后,生产环境开始出现神秘的 p99 尖峰——在中等负载下,延迟从 800ms 飙升至 8 秒,而 GPU 压力正常,模型没有报错,也找不到明显原因。你扩容了更多副本,没有改善。你对模型服务做了性能剖析,没有问题。你加了缓存,还是没用。

最终,有人查了数据库连接池的等待时间。从第三天起,它的利用率就已经高达 95%。

这是 AI 生产事故中最常见的一类,却鲜有人谈及——因为连接池耗尽的表现很像模型变慢。症状出现在错误的层级:你看到的是 LLM 调用延迟高,而不是数据库查询慢,所以定位问题往往需要数天,而用户一直在忍受降级的响应。

根本原因在于:AI 工作负载打破了传统连接池容量规划所有的内在假设。为 OLTP Web 流量设计的连接池,在加入 LLM 生成、检索和 Agent 状态持久化之后就会以难以监测、难以预判的方式崩溃。

为什么标准的容量规划公式不适用

数据库连接池容量规划的经典公式来自对高吞吐 OLTP 系统的研究。PostgreSQL 官方文档建议从以下公式出发:

connections = (core_count × 2) + effective_spindle_count

对于配备 SSD 的 4 核机器,约为 8–9 个连接。HikariCP 的文档更进一步,引用 Oracle 的基准测试表明:当团队将连接池从数百个缩减至几十个时,吞吐量提升了 50 倍。这个结论违反直觉:连接越多意味着更多的上下文切换、更激烈的锁竞争,以及更低的吞吐量。

这套数学假设了一种特定的工作负载模型——短事务、高并发、快速周转。典型的 OLTP Web 请求持有数据库连接的时间为 5–20 毫秒。以 10ms 的平均值计算,20 个连接的连接池每秒可服务 2000 个请求,才会出现排队。

LLM token 生成需要 2–60 秒,取决于输出长度。

用同样的公式套 AI 流水线:假设每个用户请求触发一次生成,生成期间持有连接 15 秒,那么 20 个连接的连接池每秒只能服务 1.3 个请求。在这个速率下,10 个并发用户的突发流量不到 10 秒就会把连接池打满,之后的请求全部排队。

连接池从来不是你关注的那个瓶颈。但一旦你在应用层接入了 LLM,它就会立刻成为瓶颈。

AI 工作负载的三种典型故障模式

模式一:检索突发

RAG 流水线对数据库的冲击方式与 API 驱动的功能截然不同。用户提交查询后,检索步骤会扇出——获取向量嵌入、查找元数据、与用户上下文做 join、按权限过滤。这可能意味着在 100ms 窗口内产生 5–15 个并行数据库调用。

在传统 API 场景中,这些会是分散在用户会话中的串行查询。在 RAG 流水线中,它们是并发的,并且同时打到连接池上。

为串行访问设计的连接池(比如 10 个连接)会被单次复杂检索打满。两个并发用户触发 20–30 个同时查询。到第三个用户,连接开始排队;到第十个用户,超时开始出现。

故障表现为检索缓慢,但实际原因是连接等待时间。向量相似性搜索 15ms 就能返回,但应用程序要等 400ms 才能拿到连接,查询甚至还没开始。

模式二:生成期间持有连接

这是代价最高的故障模式。场景很常见:应用打开一个数据库事务记录用户请求,然后调用 LLM API 生成回复,最后把结果写回事务再提交。

在传统系统中,在外部 HTTP 调用期间持有事务已经很危险。在 AI 流水线中,这个外部 HTTP 调用需要 10–30 秒,还依赖于一个延迟本身就不稳定的 GPU 服务。

在整个生成期间,连接处于空闲状态——不做任何工作,不执行任何查询,只是在模型"思考"时占着一个事务槽。与此同时,新请求不断涌入并排队等待。

曾因生成期间丢失写入(模型返回了结果,但应用崩溃没来得及持久化)而吃过亏的团队,常常把长事务作为安全保障。出发点是对的,实现方式是错的。正确做法不是一个长事务,而是两个短事务:立即持久化请求后释放连接,做生成,然后开一个新连接持久化结果。

模式三:Agent 写入风暴

多步骤 Agent 产生的写入模式是标准连接池处理起来最吃力的:大量小的、突发性的、并行的状态持久化写入。

单次 Agent 执行可能会在每次工具调用后写入检查点状态、在推理步骤之间更新工作记忆、记录工具调用日志以供可观测性使用,以及在完成时写入最终输出。在一个 20 个 Agent 并发运行、每次执行产生 5–10 次写入的系统中,短时间内会有 100–200 次小写入,中间夹杂着空闲间隙。

为稳态吞吐量设计的连接池在空闲间隙时有富余容量,随后被超过池容量的请求峰值打爆。结果是随机出现的排队等待尖峰,与任何被监控的指标都没有相关性——因为这个模式只在 Agent 层级的并发中才会涌现,在查询层级看不到。

异步取消陷阱

还有第四种故障模式,专属于异步 Python 技术栈,比其他模式更隐蔽,因为它导致的是连接泄漏而非竞争。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates