前言
这里没有说明具体那种数据库那种连接池是因为这个公式适合大多数的各种数据库和大多数连接池。
服务器连接池的数量配置很重要,太少了DB服务器工作不饱和,客户端的事务在积压;太多了服务器又响应不过来,又得频繁切换上下文,导致适得其反。那么到底配置为多少才能既充分的发挥数据库新能而又不浪费客户端的性能呢?
公式
https://github.com/brettwooldridge/HikariCP/wiki/About-Pool-Sizing上有较为详细的说明,英语好、感兴趣的同学可以自行查看,这里是对结果进行翻译并按照自己的理解来解释为什么要这么设置。
The Formula
The formula below is provided by the PostgreSQL project as a starting point, but we believe it will be largely applicable across databases. You should test your application, i.e. simulate expected load, and try different pool settings around this starting point:
connections = ((core_count * 2) + effective_spindle_count)
A formula which has held up pretty well across a lot of benchmarks for years is that for optimal throughput the number of active connections should be somewhere near ((core_count * 2) + effective_spindle_count). Core count should not include HT threads, even if hyperthreading is enabled. Effective spindle count is zero if the active data set is fully cached, and approaches the actual number of spindles as the cache hit rate falls. … There hasn’t been any analysis so far regarding how well the formula works with SSDs.
大概翻译一下就是:这个公式是PostgreSQL提供的,但是很大程度上适用于大多数数据库,你就在这个公式周围测试一下吧。公式为:connections = ((core_count * 2) + effective_spindle_count)。这个公式在很多基准测试下,在这个公式附近的值都能表现的很好。core_count是核心数,还指定不能包括超线程,effective_spindle_count在文中说的是应该为缓存失败率 。其他有的人说法是挂载的磁盘数。还有说法是可以并行处理IO的数量。但是这个数其实影响不太大了,稍微多测试一下的事儿。
我的理解
首先可能形成瓶颈的是硬盘,网络IO和内存。然后MySQL是半双工的网络模型,半双工就是在同一时刻只能进行收发的其中一个动作。所以有了core_count*2的说法,一半在写数据,一半在收数据。effective_spindle_count 是在不能命中的时候需要硬盘去寻址,读页数据,比较耗时,这时候CPU不会一直等着硬盘,可以去处理其他,也就是说如果只有一个机械硬盘,我们需要多加1根线程来处理等待硬盘读的事务。
那为什么文中会说是在这个值附近呢?而不是说很精确的就是这个值呢?我的理解是这个也和其他一些比如事务类型,缓存,内存计算有关,抛开硬盘部分不说,如果事务类型都是很简单的计算,同时缓存能够100命中的话,那这个连接池数量还可以加,因为内存这时候可能网络IO成了瓶颈,可以多加一些链接来满足内存的运算量。如果本身事务比较复杂,内存计算不及时,那么这时候再加链接数量反倒增加了上下文切换的压力。
欢迎评论区交流~
|