Database 最大连接池是否也限制到数据库的最大连接数?

Database 最大连接池是否也限制到数据库的最大连接数?,database,spring-boot,hikaricp,Database,Spring Boot,Hikaricp,我正在使用hikari cp和spring boot应用程序,它有超过1000个并发用户。 我已经设置了最大池大小- spring.datasource.hikari.maximum-pool-size=300 当我使用 show processlist; 它显示的最大值为300,等于池的大小。它的增加量永远不会超过最大池。这是有意的吗? 我认为池大小意味着保持连接,以便在将来需要数据库请求时可以重用连接,但在需要时可以进行更多连接 另外,当我删除max pool配置时,我会立即得到- Hi

我正在使用hikari cp和spring boot应用程序,它有超过1000个并发用户。 我已经设置了最大池大小-

spring.datasource.hikari.maximum-pool-size=300
当我使用

show processlist;
它显示的最大值为300,等于池的大小。它的增加量永远不会超过最大池。这是有意的吗? 我认为池大小意味着保持连接,以便在将来需要数据库请求时可以重用连接,但在需要时可以进行更多连接

另外,当我删除max pool配置时,我会立即得到-

HikariPool-0-连接不可用,请求在30000ms后超时


如何解决此问题。请提前感谢。

是的,这是有意的。引述:

此属性控制池允许达到的最大大小,包括空闲连接和正在使用的连接。基本上,该值将确定到数据库后端的实际连接的最大数量。合理的值最好由您的执行环境决定。当池达到此大小且没有空闲连接可用时,对
getConnection()
的调用将在超时前阻塞最多
connectionTimeout
毫秒。请阅读。默认值:10

因此,基本上,当所有300个连接都在使用中,并且您正在尝试建立第301个连接时,Hikari不会创建新的连接(因为
maximumPoolSize
是绝对最大值),而是会等待(默认情况下30秒),直到连接再次可用

这也解释了为什么会出现您提到的异常,因为默认值(在未配置
maximumPoolSize
时)是10个连接,您可能会立即到达

要解决此问题,您必须找出这些连接被阻止超过30秒的原因。即使在有1000个并发用户的情况下,如果查询只需要几毫秒或最多几秒钟,也应该没有问题

增加池大小 如果调用非常复杂的查询需要很长时间,那么有几种可能性。第一个是增加池的大小。但是,不建议这样做,因为计算最大池大小的建议公式为:

connections = ((core_count * 2) + effective_spindle_count)
引述该条:

多年来,一个在许多基准中都表现良好的公式是 为了获得最佳吞吐量,活动连接的数量应该在某个地方 近
((芯数*2)+有效芯数)
。核心计数不应包括 HT线程,即使启用了超线程。有效主轴计数为零,如果 活动数据集被完全缓存,并且接近实际的轴数 当缓存命中率下降时。。。到目前为止还没有任何关于这方面的分析 该配方对固态硬盘的效果如何

正如同一篇文章中所述,这意味着一个4核服务器和一个硬盘应该只有大约10个连接。即使您可能有更多的内核,我假设您没有足够的内核来保证正在进行的300个连接,更不用说进一步增加了


增加连接超时 另一种可能是增加连接超时。如前所述,当所有连接都在使用时,默认情况下会等待30秒,即连接超时

您可以增加此值,以便应用程序在超时前等待更长时间。如果复杂查询需要20秒,并且连接池中有300和1000个并发用户,则理论上应将连接超时至少配置为
20*1000/300=67秒

但是请注意,这意味着您的应用程序可能需要很长时间才能向用户显示响应。如果您有67秒的连接超时,并且在复杂查询完成之前还有20秒,那么您的用户可能需要等待一分半钟


提高执行时间 如前所述,您的主要目标是找出查询耗时如此之长的原因。连接池为300,连接超时为30秒,并发用户为1000,这意味着您的查询在完成之前至少需要9秒,这是一个很大的问题

尝试通过以下方式缩短执行时间:

  • 添加适当的索引
  • 正确地编写查询
  • 改进数据库硬件(磁盘、核心、网络等)
  • 通过引入分页来限制正在处理的记录数量
  • 分工。看看是否可以将查询拆分为较小的查询,从而生成中间结果,然后在另一个查询中使用,依此类推。只要您不在事务中工作,就可以在事务之间释放连接,从而允许您以牺牲某些性能为代价为多个用户提供服务
  • 使用缓存
  • 预先计算结果:如果您正在进行一些资源密集型计算,您可以尝试在应用程序不经常使用的时刻(例如,在夜间)预先计算结果,并将这些结果存储在可以轻松查询的其他表中

连接池为300,连接超时为30秒,并发用户为1000,这意味着您的查询至少需要9秒才能完成,这是一个很大的问题。
您如何计算它?@kamalhm我使用了
超时/(并发用户/最大池)
,因此
30/(1000/300)