bigywater.tech
Spring · 166

HikariCP 连接池大小设多少:不同大小下的吞吐和等待

连接池到底设多大?池越大吞吐越高吗?等待型查询和 CPU 密集型查询有什么区别?这篇用 64 个线程在本机 MySQL 上把 maximum-pool-size 从 1 逐个加到 64,看吞吐和获取连接的等待。

163 到 7718
查询是 sleep 5 ms 时,maximum-pool-size 从 1 加到 64,吞吐(次/秒)的变化
318 到 434
查询是 CPU 密集的全表扫描时,池从 8 加到 64(8 倍),吞吐(次/秒)只增加这么多
P99 约 5 秒
池很小时获取连接的 P99 等待接近整个 5 秒测试时长:有线程几乎拿不到连接

等待型查询

实测 · 本机执行输出
  maximum-pool-size= 1:吞吐 163 次/秒 | 获取连接 平均 403.30 ms P99 5327.9 ms | 总耗时 平均 409.95 ms P99 5334.5 ms | 失败 0
  maximum-pool-size= 2:吞吐 324 次/秒 | 获取连接 平均 195.89 ms P99 5123.0 ms | 总耗时 平均 202.33 ms P99 5129.4 ms | 失败 0
  maximum-pool-size= 4:吞吐 633 次/秒 | 获取连接 平均 96.11 ms P99 5006.7 ms | 总耗时 平均 102.54 ms P99 5014.3 ms | 失败 0
  maximum-pool-size= 8:吞吐 1253 次/秒 | 获取连接 平均 45.01 ms P99 1565.7 ms | 总耗时 平均 51.33 ms P99 1572.1 ms | 失败 0
  maximum-pool-size=16:吞吐 2407 次/秒 | 获取连接 平均 20.35 ms P99 376.8 ms | 总耗时 平均 26.72 ms P99 383.3 ms | 失败 0
  maximum-pool-size=32:吞吐 4516 次/秒 | 获取连接 平均 7.89 ms P99 0.2 ms | 总耗时 平均 14.22 ms P99 27.3 ms | 失败 0
  maximum-pool-size=64:吞吐 7718 次/秒 | 获取连接 平均 1.88 ms P99 0.0 ms | 总耗时 平均 8.30 ms P99 11.7 ms | 失败 0

数据库里只是等待时,吞吐随池大小接近线性增长。

CPU 型查询

实测 · 本机执行输出
  maximum-pool-size= 1:吞吐 82 次/秒 | 获取连接 平均 837.28 ms P99 5821.7 ms | 总耗时 平均 851.62 ms P99 5834.6 ms | 失败 0
  maximum-pool-size= 2:吞吐 138 次/秒 | 获取连接 平均 470.16 ms P99 5391.0 ms | 总耗时 平均 485.99 ms P99 5403.8 ms | 失败 0
  maximum-pool-size= 4:吞吐 245 次/秒 | 获取连接 平均 252.86 ms P99 5201.0 ms | 总耗时 平均 270.04 ms P99 5216.0 ms | 失败 0
  maximum-pool-size= 8:吞吐 318 次/秒 | 获取连接 平均 180.11 ms P99 5088.6 ms | 总耗时 平均 205.61 ms P99 5111.4 ms | 失败 0
  maximum-pool-size=16:吞吐 361 次/秒 | 获取连接 平均 137.52 ms P99 4824.2 ms | 总耗时 平均 180.74 ms P99 4846.8 ms | 失败 0
  maximum-pool-size=32:吞吐 405 次/秒 | 获取连接 平均 88.73 ms P99 2442.0 ms | 总耗时 平均 162.42 ms P99 2523.3 ms | 失败 0
  maximum-pool-size=64:吞吐 434 次/秒 | 获取连接 平均 33.71 ms P99 907.7 ms | 总耗时 平均 149.13 ms P99 966.6 ms | 失败 0

CPU 密集的查询在池达到 8 之后增长很慢。

分步演示

连接池
本步的对象

    本文用到的工具与边界

    • 本机 macOS 27 arm64 / OpenJDK 21.0.12(Homebrew) / Spring Boot 4.0.8(Spring Framework 7.0.9、Tomcat 11.0.24) / Spring Cloud 2025.1.3;用 javac 编译、java 直接运行,依赖由 Maven 从 Maven Central 解析;数字每次运行会有小幅抖动(Spring Boot 4.0.8 的 starter-jdbc 与 HikariCP,spring.datasource.hikari.maximum-pool-size 与 minimum-idle 同时设成同一个值,connection-timeout 30 秒;MySQL 是本机自己起的实例,与应用同机,本机 10 个 CPU 核;64 个线程闭环,持续 5 秒,每个池大小只跑了一次;demo.big 表 10 万行)
    • 没有验证:应用与数据库分机、有真实网络延迟时的最优池大小;多个并发混合查询;事务持有连接时间更长时的池耗尽现象(见 HikariCP 默认值一篇);「池大小等于 CPU 核数的两倍加一」之类经验公式是否成立;每个池大小只测了一次,没有重复;MySQL 自身的 max_connections 与线程缓存的影响;P99 在线程严重不公平时的含义(本次池小时少数线程长时间拿不到连接)
    京ICP备2026067502号-1京公网安备11010502063487号