网络知识 娱乐 总结一下各大数据源的优缺点

总结一下各大数据源的优缺点

为什么会有数据源?

古老的JDBC连接很麻烦,执行一次SQL就要打开关闭一个连接,这样的方式会导致用户每次请求都要向数据库建立链接而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、宕机。
图为原始JDBC的连接情况
在这里插入图片描述
由于原始的JDBC不具有高可用性所以诞生了数据源的概念,也可以理解为数据池,连接放入池中,用的时候直接拿不用去新建连接,可用性大大提高。
在这里插入图片描述
在这里插入图片描述

常用的数据源

JDBC针对数据库连接池定义的接口java.sql.DataSource,所有的数据库连接池实现都要实现该接口。
我们常用的开源的数据源有很多,除了Druid和HikariCP其他的基本上已经过时了

  • C3P0:开源JDBC连接池,实现数据源和JNDI绑定,包括实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。单线程,性能较差,适用于小型系统,代码600KB左右。
  • BoneCP:开源的快速的 JDBC 连接池。只有四十几K(运行时需要log4j和Google Collections的支持)。另外个人觉得 BoneCP 有个缺点是,JDBC驱动的加载是在连接池之外的,这样在一些应用服务器的配置上就不够灵活。官方说法BoneCP是一个高效、免费、开源的Java数据库连接池实现库。设计初衷就是为了提高数据库连接池性能,完美集成到一些持久化产品如Hibernate和DataNucleus中。特色:高度可扩展,快速;连接状态切换的回调机制;允许直接访问连接;自动化重置能力;JMX支持;懒加载能力;支持XML和属性文件配置方式;较好的Java代码组织。
  • DBCP:Database Connection Pool,一个依赖Jakarta commons-pool对象池机制的数据库连接池,单独使用dbcp需要3个包:common-dbcp.jar,common-pool.jar,common-collections.jar,预先将数据库连接放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完再放回。单线程,并发量低,性能不好,适用于小型系统。
  • Tomcat Jdbc Pool:Tomcat在7.0以前都是使用common-dbcp做为连接池组件,但是dbcp是单线程,为保证线程安全会锁整个连接池,性能较差,dbcp有超过60个类,也相对复杂。Tomcat从7.0开始引入新增连接池模块叫做Tomcat jdbc pool,基于Tomcat JULI,使用Tomcat日志框架,完全兼容dbcp,通过异步方式获取连接,支持高并发应用环境,超简单,核心文件只有8个,支持JMX,支持XA Connection。
  • Druid:阿里巴巴的数据源,功能齐全。淘宝和支付宝专用数据库连接池,但它不仅仅是一个数据库连接池,它还包含一个ProxyDriver,一系列内置的JDBC组件库,一个SQL Parser。支持所有JDBC兼容的数据库。Druid针对Oracle和MySQL特别优化,比如Oracle的PS Cache内存占用优化,MySQL的ping检测优化。Druid提供SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。Druid能够提供强大的监控和扩展功能,是一个可用于大数据实时查询和分析的高容错、高性能的开源分布式系统,尤其是当发生代码部署、机器故障以及其他产品系统遇到宕机等情况时,Druid仍能够保持100%正常运行。主要特色:为分析监控设计;快速的交互式查询;高可用;可扩展;简单SQL语句用时10微秒以内,复杂SQL用时30微秒。通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter就是通过Druid的SQL Parser分析语义实现的。
  • HikariCP:SpringBoot默认的数据源,号称是最快的数据源。
    • 字节码精简 :优化代码,直到编译后的字节码最少,这样CPU缓存可以加载更多的程序代码;
    • 优化代理和拦截器:减少代码,例如HikariCP的Statement proxy只有100行代码,只有BoneCP的十分之一;
    • 自定义数组类型(FastStatementList)代替ArrayList:避免每次get()调用都要进行range check,避免调用remove()时的从头到尾的扫描;
    • 自定义集合类型,使用ConcurrentBag提高并发读写的效率;
    • 其他针对BoneCP缺陷的优化,比如对于耗时超过一个CPU时间片的方法调用的研究。

Druid 和 HikariCP 二者如何比较

不具有可比性,HikariCP 追求性能,Druid 偏向监控;Druid 默认开启公平锁导致性能下降,有阿里生产环境大数据验证。

补充

SpringBoot默认的是HikariDataSource,因为他非常高性能,Hikari的高性能得益于最大限度的避免锁竞争
性能方面 hikari>druid>tomcat-jdbc>dbcp>c3p0
druid功能最为全面,sql拦截等功能,统计数据较为全面,具有良好的扩展性

参考文章