很多工程师习惯于使用一个组件时,参数设置依赖于默认值。或者有时候希望依赖数据分析获取到更合适的值,最终发现考虑的数据过于片面或者数据难以收集最终还是拍脑袋决定了参数的大小。今天咱们就以数据库连接数参数为例说明怎么去设计参数。
一、前提知识
先说明一下数据库连接数大小是什么概念。数据库连接数一般指数据库连接池。 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间
超过最大空闲时间
的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数制约的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。
数据库连接池的最小连接数和最大连接数的设置要考虑到下列几个因素:
1.最大连接数
它(maxActive)是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求将被加入到等待队列中,这会影响之后的数据库操作。
- 最小连接数
它(minIdle)是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费。
- 最小连接数与最大连接数差距
最小连接数与最大连接数相差太大,那么最先的连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接。不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,它将被放到连接池中等待重复使用或是空闲超时后被释放。
二、怎样决定最大连接数?
很多朋友觉得自己的系统需要很大的吞吐,并发量高,那就应该尽量将连接数设置的大一些。我们来看之前歪果仁做的一个实验:
歪果仁对
Oracle
数据库进行了压力测试,模拟9600
个并发线程来操作数据库,每两次数据库操作之间sleep 550ms
,刚开始设置的线程池大小为2048
。
结果:
每个请求要在连接池队列里等待 33ms
,获得连接之后,执行SQL
需要耗时77ms
, CPU
消耗维持在95%
左右;
接下来,我们将连接池的大小改小点,设置成
1024
,其他测试参数不变。
结果:
获取连接等待时长基本不变,但是 SQL
的执行耗时降低了。
接下来,我们再设置小些,连接池的大小降低到
96
,并发数等其他参数不变。
结果:
每个请求在连接池队列中的平均等待时间为 1ms
, SQL
执行耗时为 2ms
.
其实,对于一般情况来说,最大连接数200
是DBA
看了都会害怕的数值。200
个连接,就意味着有200
个并发通道。
- 从系统影响来说,并发量高时,它会影响
CPU
、内存、磁盘IO
的指标,甚至可能打垮服务器。 - 从业务影响来说,很多
SQL
并行执行,增加了SQL
之间相互影响的几率,造成更高的锁等待率。
连接数是对数据库服务器的保护,对一般数据库服务器质量还可以的SSD
硬盘设备,无慢查询,平均数据库处理时长在2ms
以下的请求(1
个连接每秒便可以处理500
个请求),那么最大连接数10
可达到TPS
到5000
。对于一般的系统足够用。更精确的还是要靠实际压测结果以及业务场景。
三、举个工作中的实际例子
有一个数据库,通过一个代理实例统一管理具体实例,一共部署了13
台实例。每台实例大约承接了6000QPS
,我们设置了连接数大于260
时报警,也就是每台实例大约20
个连接。那么20
个连接承接6000QPS
,一个连接承接300QPS
,从而可以推导出平均每次SQL
操作大约耗时为1s / 300qps = 3.3ms
。更精确的还是要靠实际压测结果以及业务场景。
这里还只分析了CPU
的影响,实际还需要考虑容量
的影响。可参考:82.1W/S的QPS到底大不大?
参考文档:https://mp.weixin.qq.com/s/RUtKqzLn8oco8AAORGzKPA