`
deepinmind
  • 浏览: 445012 次
  • 性别: Icon_minigender_1
  • 来自: 北京
博客专栏
1dc14e59-7bdf-33ab-841a-02d087aed982
Java函数式编程
浏览量:40842
社区版块
存档分类
最新评论

数据库连接池简析

阅读更多
序言


我参与的这些项目都用到了数据库连接池,这自然是有它的原因的。有时候我们可能会忘了当初为什么使用了某种设计模式或者某项技术,因此很有必要从头再推理一遍。每项技术或者技术决策肯定都有它的优势和劣势,如果发现它没有缺点的话,那你最好仔细想想是不是漏掉了什么。

数据库连接的生命周期

数据库的每一个读写操作都需要有一个连接。我们来看下数据库连接的调用流是什么样的:



调用流程是这样的:

1. 应用程序的数据访问层请求DataSource来获取一个数据库连接。
2. DataSource使用数据库驱动来打开一个数据库连接。
3. 创建数据库连接,同时打开了一个TCP socket。
4. 应用程序进行数据库的读写。
5. 连接已经不再需要了,因此关闭它。
6. 关闭socket。

很容易可以看到,数据库连接的打开和关闭是非常昂贵的。PostgreSQL会为每个客户端连接分配一个单独的操作系统进程,因此高频率的打开关闭操作会使你的数据库管理系统负担很重。

重用数据库连接最主要的原因是:

1. 减少应用程序与数据库之间创建/销毁TCP连接的开销
2. 减少JVM的垃圾对象。

池还是非池

我们来将不用连接池的实现和HikariCP进行对比,HikariCP应该是最高效的连接池框架了。

测试程序会创建并关闭1000个连接。

private static final Logger LOGGER = LoggerFactory.getLogger(DataSourceConnectionTest.class);
 
private static final int MAX_ITERATIONS = 1000;
 
private Slf4jReporter logReporter;
 
private Timer timer;
 
protected abstract DataSource getDataSource();
 
@Before
public void init() {
    MetricRegistry metricRegistry = new MetricRegistry();
    this.logReporter = Slf4jReporter
            .forRegistry(metricRegistry)
            .outputTo(LOGGER)
            .build();
    timer = metricRegistry.timer("connection");
}
 
@Test
public void testOpenCloseConnections() throws SQLException {
    for (int i = 0; i < MAX_ITERATIONS; i++) {
        Timer.Context context = timer.time();
        getDataSource().getConnection().close();
        context.stop();
    }
    logReporter.report();
}



图中显示的是打开及关闭连接所花费的时间,当然这个时间越短则越好。



使用了连接池的实现要比没有连接池快600倍。我们的企业级系统中有大量的应用,光是一个批处理的系统每小时就会创建两百万的数据库连接,因此像这样两个数量级差距的优化当然是应该考虑的。


   
类型不使用连接池的情况使用了连接池的情况
最短时间74.5514140.002633
最长时间146.69324125.528047
平均时间78.2165490.128900
标准差5.94383353.969438
中位数76.1504400.003218


为什么连接池如此高效?

要明白为什么连接池的性能会这么好,我们需要分析下连接池的调用流:



每当请求一个连接的时候,使用了连接池的数据源都会先通过连接池来获取一个新的连接。连接池只有当没有可用的连接并且还没有达到连接池上限的时候才会去创建新的连接。而连接池的close()方法只是把连接扔回到池里而已,并不是真的要关闭它。



更快,更安全

连接池扮演了连接请求的一个有界缓冲区的角色。如果流量瞬间出现了抖动连接池会使它变得平缓,而不是去耗尽所有的数据库资源。

等待超时的机制就像一个安全挂钩,它避免数据库服务器出现过高的负载。如果有个应用想要使用了过多的数据库资源,连接池会减缓它的调用,以免它将数据库压垮了(这样整个企业系统都会受到影响)。


能力越大,责任越大

所有的这些好处都是有代价的,连接池的配置又带来了额外的复杂性(尤其在大型的企业级应用中)。因此有了它并不能就高枕无忧了,你还得去注意连接池的许多配置项,比如:

1. 连接的最小数量
2. 连接池的最大数量
3. 最长空闲时间
4. 获取连接超时时间
5. 超时的重试次数

我的下一篇文章将会深入介绍企业级应用中数据库连接池面临的一个挑战,同时介绍下Flexy Pool是如何帮助你找到合适的连接池大小的。

代码在Github上可以下载。
原创文章转载请注明出处:http://it.deepinmind.com

英文原文链接
2
0
分享到:
评论
3 楼 cuishuangjia 2014-05-05  





DBTOOLS支持ORACLE,MYSQL,SQLSERVER,POSTGRE,DB2数据库相互转换功能
目前支持中文和日文
功能:
1。将数据库中的表结构和数据保存到EXCEL中。
2。将EXCEL中的数据,同步到数据库中。
3。当表结构发生变化时,数据不会丢失。
4。程序执行前后,表中的数据发生了哪些变化
5。根据EXCEL中的表结构,生成建表语句SQL文。
6。多用户使用该软件时,可以随时记录某个用户对数据库的操作。
7。可以为进行压力测试,自动生成数据。
8。导出表结构,根据表结构和数据库中的表结构进行差分。
9。导出DB结构,和现有环境DB进行表结构差分
10。导出用户自定义表结构,根据表结构导入,导入数据前对EXCEL校验进行数据库验证
和业务逻辑验证
11。单体测试,结合测试解决方案。

作者邮件:cuishuangjia@gmail.com
企鹅群:数据库第三方工具交流  184715368


DbTools的YouTu展示视频
http://youtu.be/jfRwDUpPRLw

百度网盘下载地址:
http://pan.baidu.com/s/1pCjPt
(包含有视频讲解文件)
2 楼 deepinmind 2014-05-04  
cywhoyi 写道
我参与的一个连接池开源组织BoneCP,虽然我没有测试过,不过连接池的特性其实是差不多的,不过BoneCP提出分区,分区之间是单独的生命周期的概念,避免了GC所带来性能瓶颈。


赞,BoneCP我没了解过,回头看看~
1 楼 cywhoyi 2014-05-04  
我参与的一个连接池开源组织BoneCP,虽然我没有测试过,不过连接池的特性其实是差不多的,不过BoneCP提出分区,分区之间是单独的生命周期的概念,避免了GC所带来性能瓶颈。

相关推荐

Global site tag (gtag.js) - Google Analytics