数据库连接池的大小

国庆期间闲来无事,写了一个简单的小程序,小程序名称叫做 IT藏经楼。目的是分享这些年自己积累的一些学习材料,方面大家查找使用,包括电子书、案例项目、学习视频、面试题和一些PPT模板。里面所有材料都免费分享。目前小程序中只发布了非常小的一部分,后续会陆续上传分享。当前版本的小程序页面也比较简单,还在逐渐的优化中。

基本上来说,大部分项目都需要跟数据库做交互,那么数据库连接池的大小设置成多大合适呢?一些同学可能会很随意的告诉你:没关系,尽量设置的大些,比如设置成200, 这样数据库性能会高写,吞吐量也会大些。 真的是这样吗?

关于数据库连接池大小的设置,每一个开发都有可能在这一环节掉进坑里。事实上大部分程序员可能都会依靠自己的直觉去设置它的大小,设置成100?思量许久后,应该差不多吧?

案例
某个团队对Oracle数据库进行了压力测试,模拟9600个并发线程来操作数据库,每两次数据库操作之间sleep 550ms,最开始的时候设置的线程池大小为2048。测试结果是:每个请求要在连接池队列里面等待33ms,获得连接之后,执行SQL需要耗时77ms,CPU消耗维持在95%左右。

接下来将连接池大小改小点,设置成1024, 其他测试参数不变,测试结果:获取连接等待时长基本不变,但是SQL的执行耗时降低了。

接下来再设置小一些,连接池大小降低到96, 并发数等其他参数不变,测试结果:每个请求再连接池队列中的平均等待时间为1ms,SQL执行耗时为2ms。

我们没有调整任何东西,仅仅只是将数据库连接池的大小降低了,这样就能把之前平均100ms的相应时间缩短到了3ms,吞吐量指数级上升。

为什么会有这种效果?
我们不妨想一下,为啥Nginx内部仅仅使用了4个线程,其性能就大大超越了100个线程的Apache httpd?要知道,即使是单核CPU的计算机也能“同时”运行着数百个线程,但我们其实都知道,这只不过是操作系统快速切换时间片,跟我们玩的一个小把戏罢了。

一核CPU同一时刻只能执行一个线程,然后操作系统切换上下文,CPU核心快速调整,执行另外一个线程的代码,不停反复,给我们造成了所有进程同时运行的假象。

其实,在一核CPU的机器上,顺序执行A和B永远比通过时间分片切换“同时”执行A和B要快,一旦线程的数量超过了CPU核心的数量,再增加线程数系统就只会更慢,而不是更快,因为这里涉及到上下文切换耗费的额外的性能。

其他应该考虑到的因素
当我们再寻找数据库的性能瓶颈时,大致可归为三类:
a. CPU
b. 磁盘IO
c. 网络IO

也许你会说,还有内存,内存的确是需要考虑的,但是比起磁盘IO和网络IO,就稍显微不足道了。

假设我们不考虑磁盘IO和网络IO,那就很好定论了,在一个8核的服务器上,数据库连接数/线程数设置为8能够提供最优的性能,如果再增加连接数,反而会因为上下文切换导致性能下降。

大家都知道,数据库通常把数据存储再磁盘上,而磁盘通常是由一些旋转着的金属碟片和一个读写头组成的。读写头同一时刻只能出现在一个位置,当它需要再次执行读写操作的时候,它必须“寻址”到另外一个位置才能完成任务。所以这里就有了寻址的耗时,此外还有旋转耗时,读写头需要等待磁盘碟片上的目标数据“旋转到位”才能进行读写操作。在这段时间内,线程是出于“阻塞”等待状态,也就是说没干啥正事,此时操作系统可以将这个空闲的CPU核心用于服务其他线程。

这里我们可以总结一下,当你的线程处理的是I/O密集型业务时,便可以让线程/连接数设置的比CPU核心数大一些,这样就能够在同样的时间内,完成更多的工作,提升吞吐量。

那么设置成多少合适呢?这要取决于磁盘,如果你使用的是SSD固态硬盘,它不需要寻址,也不需要旋转碟片,意味着线程阻塞的时间很少,所以接近于CPU核心数的线程会发挥出更高的性能。只有当阻塞密集型时,更多的线程数才能发挥更好的性能。

上面我们了解了磁盘IO,接下来我们谈谈网络IO。网络IO其实也非常的相似,通过以太网接口读取数据时也会造成阻塞,10G带宽会比1G带宽的阻塞耗时少一些,而1G带宽又会比100M带宽的阻塞少一些。通常情况下,我们把网络IO放到第三顺位来考虑。

连接数计算公式

下面公式由PostgreSQL提供,它适用于市面上绝大部分数据库产品。还有,你应该模拟预期的访问量,并通过下面的公式先设置一个偏合理的值,然后在实际的测试中,通过微调来寻找最合适的连接数大小。
连接数 = (核心数 * 2) + 有效磁盘数

按照这个公式,如果你的服务器CPU是4核的,连接池大小应该为(4 * 2)+ 1 = 9,取个整我们就设置为10。如果你跑个性能测试就可以看到,它能轻松支撑3000用户以6000TPS的速率并发执行简单查询的场景。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无法无天过路客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值