如何设置合理的mysql连接池数

目的
鉴于目前数据库连接数管理混乱,RD申请资源设定连接池没有进行精确考量,造成数据库连接数资源紧张的问题。

在此文档中将详细介绍连接池的由来,作用以及MySQL针对连接的处理,帮助RD能够设定合理的连接数,避免资源浪费和异常发生。

什么是连接池
在系统设计中,我们常常会使用到池(pool)的概念,如:数据库连接池,http连接池,socket连接池,线程池等。使用池结构可以明显的提高应用程序速度,改善效率和提高系统资源的利用。

在数据库中,连接是一种关键而有限的资源。通常在MySQL中(不考虑企业版连接池功能)一个数据库连接对应一个物理数据库连接,每次操作都要打开一个物理连接,使用后关闭连接,这样会造成系统性能低下。

应用端数据库连接池的解决方案是在应用程序启动时就建立足够的数据库连接,并把这些连接组成一个连接池,由应用程序动态地对池中的连接进行申请、使用和释放。对于多于连接池中连接数的并发请求,应该在请求队列中排队等待。并且应用程序可以根据池中连接的使用率,动态增加或减少池中的连接数。 连接池技术尽可能多地重用了消耗的内存资源,大大节省了内存,提高了服务器的服务效率,能够支持更多的客户服务。通过使用连接池,将大大提高程序运行效率,同时,我们可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。

无连接池的连接建立
TCP建立三次握手
MySQL认证的三次握手
真正的SQL执行
MySQL进行连接关闭
服务器TCP四次握手关闭
后续请求进行1-5循环
有连接池的连接建立
应用服务器启动按照事先指定的参数初始化创建数据库连接
TCP建立三次握手
MySQL认证的三次握手
请求从连接池中获取空闲连接,进行SQL执行
完成请求将连接资源放入连接池,数据库连接进入等待状态(idle)
后续请求按照4-5步骤即可
连接池的优势
明显减少了网络开销
数据库最大连接数可以得到控制,防止短链接请求短时间将数据库连接资源占满
系统层面减少TIME_WAIT状态,防止端口占用导致的堵塞
连接数预估
合理的设置连接池数量能够避免连接频繁的重建与释放,对系统的性能有很大的影响。设置合适的数目即能够避免应用程序频繁的新建立数据库连接,又可以控制数据库的最大连接数,防止连接异常增长造成数据库资源损耗。

根据通常的流量请求路径,一般连接池的配置原则为:web连接池>应用连接池>数据库连接池,呈为一个漏斗模型。 因此数据库连接数往往要远小于web请求数目,具体的计算方式为
image.png
单应用节点连接数=数据库并发/( 应用节点数*数据库事务处理速度 )

例:

业务web最大并发请求1万,HttpClient连接数缓存队列默认为4096。数据库端平均响应时间100ms(1个连接每秒处理10个事务),由于这边db层面的线程池不做考虑。部署10个app服务器时,app端数据库连接池计算为

4096/(10*10)=40。
针对不同服务的平均响应时间和到数据库端的平均请求可以设置合理的连接池大小。

连接池设置技巧
连接池功能通常分为初始化连接、最大连接、连接超时时间、连接重试。

初始化连接:应用服务器启动时,根据init值设定的连接数。

最大连接:当应用程序在已有的连接池中申请不到新连接时,连接池会在不超过max值的情况下建立新的连接。

连接超时时间(idle_time):当连接空闲时间超过该空闲时间,如果连接池中的连接数大于init值,会对该连接进行回收。

连接重试:当应用程序通过连接池获取到连接时,如果mysql端连接超时会进行重试。

根据上文的计算方式计算出来连接数的大小,我们可以按照比例设置初始化连接:

如每台服务器结算出来最大40个连接。我们可以将init设为20,将max设为50。

常见问题
1.应用端报获取不到连接

如果mysql端正常,一般是应用端连接池到达max值,需要扩大max值或者添加新的应用服务器
2.应用连接报连接timeout,CommunicationsException: The last packet successfully received from the server was xxx milliseconds ago

mysql会对长期idle的连接进行释放,如果连接池超时时间超过mysql的wait_timeout值,就会报错。
解决方式:调低连接池timeout参数阈值。涉及参数:maxLifetime;idleTimeout;

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://www.fengpt.cn/archives/如何设置合理的mysql连接池数