数据库连接池分析

摘要

承接上篇数据库连接(1)从jdbc到mybatis,介绍下数据库连接池技术

为什么需要连接池

在上一篇中我们介绍说客户端建立一次连接耗时太长(建立连接,设置字符集,autocommit等),如果在每个sql操作都需要经历建立连接,关闭连接。不仅应用程序响应慢,而且会产生很多临时对象,应用服务器GC压力大。另外数据库server端对连接也有限制,比如MySQL默认151个连接(实际环境中一般会调大这个值,尤其是多个服务时)

现在面临的问题就是如何提高对稀缺性的资源高效管理。因为客户端与数据库的连接本质就是tcp请求,加上基于tcp协议封装的mysql请求。那么通常解决这类问题,我们有两种方式,一种是池话技术,即使用一个容器,提前创建好连接,请求时直接从池子里面拿,另外一种就是利用IO多路复用技术。利于在spring5中,mongo ,cassandra等数据库的访问就可以利用reactive来实现了,但是关系型数据库不行,原因在于关型数据库的访问目前都是基于JDBC,JDBC操作数据库的流程,建立connection,构建Statement,执行这一套是串行的,阻塞型。一个事务中的多个操作只能在同一个连接中完成。所以不能使用IO多路复用技术,是受限于JDBC的阻塞。对于其他语言,是可以的,比如nodejs

所以我们使用池话技术来提供数据库访问

数据库连接池与线程池的区别

通常,程序员在业务开发中经常使用的是线程池,利用CPU多核,来并发处理任务,提高效率。数据库连接池与线程池同属于池化技术,没有太大区别,都是需要管理池的大小,资源控制。不同的数据库连接池中放的是connection,同时还需要管理事务,所以通常数据库连接池中会对这个进行优化

从连接池中取连接执行sql操作,多了两步设置connection autocommit属性操作 数据库连接池分析

通过将connection分成两组,来提供效率 数据库连接池分析

开源连接池技术介绍

数据库连接池分析

一个基本的数据库连接池包括几大部分

  • 取出连接

  • 放回连接

  • 异步/同步处理线程

    进行创建连接和销毁连接 对于一个数据库连接池的根本就在于并发容器的实现,也是决定连接池的效率高低,常见的连接池配置如下

目前的开源数据库连接池主要有以下, 数据库连接池分析

C3P0,和DBCP是出现的比较早的数据库连接,主要用于hibernate,和tomcat6.0以下,比较稳定,在低并发的情况下,工作还可以,但是高并发下,性能比较差,所以在tomcat6,又重写了一个jdbc-pool,来替代DBCP。

Druid阿里巴巴开源的高性能数据库连接池,目前基本是各大互联网公司的标配了,加上又是国内的,文档比较易读,所以流行度比较高,另外一个是hikariCP,性能比较高,目前普及度还不是特别高。

那为什么C3P0和DBCP的性能比较低呢?前面提到数据库连接池本质上就是一个并发容器的实现。通常我们可以利用List+机制实现。或者使用jdk原生的,比如CopyOnWriteList这样的结构 而锁通过有两种,一种JVM级别的synchronized,一种是JDK提供的ReentrantLock,两者在语义上并没有多大区别,互斥,内存可见,可重入。JDK5中引入ReentrantLock时,性能比synchronzied要好很多,而在JDK6中,经过优化后的,两者并无太大性能上区别。所以ReentrantLock更多优势在于

  • 可以中断等待的线程 一直拿不到锁的等待线程,可以中断掉,避免出现死锁

  • 可以结合Condition,更加灵活控制线程

看下com.mchange.v2.c3p0.DriverManagerDataSource 的实现

在获取连接的时候首先在一个synchonized中去获取java.sql.Driver,

具体的连接池管理是BasicResourcePool,可以看下代码,里面全都是synchronized方法。并发性能怎么能好。

再来看下Druid的实现,DruidDataSource

并发环境下去拿连接时,并没有在读操作上加锁,比互斥锁的性能要高 互斥锁是一种比较保守的策略,像synchronized,它避免了写写冲突,写读冲突,和读读冲突,对于数据库连接池,应用程序来拿,是一个读操作比较多的,允许多个读同时操作,能够提高系统的并发性。

在创建连接线程,销毁连接线程中增加写锁

想了解更多数据库知识,扫描下方二维码 数据库连接池分析

HikariCP在读写锁的基础上进行了进一步的优化 https://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole

参考

https://my.oschina.net/javahongxi/blog/1523745

原文 

https://mp.weixin.qq.com/s?__biz=MzI4NjI3MDc1NA==&mid=2247483720&idx=1&sn=365d6fa7d2e69f5f4cc6824599c3da8a&chksm=ebde3505dca9bc1384d894aaff335903ba74e8768059a1a75409d7a5f64a2b4f54740ed5bea2&mpshare=1&scene=23&srcid=0415gDeQW3qW7kWmT6NwW1r8#rd

本站部分文章源于互联网,本着传播知识、有益学习和研究的目的进行的转载,为网友免费提供。如有著作权人或出版方提出异议,本站将立即删除。如果您对文章转载有任何疑问请告之我们,以便我们及时纠正。

PS:推荐一个微信公众号: askHarries 或者qq群:474807195,里面会分享一些资深架构师录制的视频录像:有Spring,MyBatis,Netty源码分析,高并发、高性能、分布式、微服务架构的原理,JVM性能优化这些成为架构师必备的知识体系。还能领取免费的学习资源,目前受益良多

转载请注明原文出处:Harries Blog™ » 数据库连接池分析

赞 (0)
分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址