这世界上已经有了这么多的、开源的数据库连接池, 为什么要再写一个?

1

这位老兄叫做Brett Wooldridge, 1989年毕业于新奥尔良洛约拉大学,计算机学士(你没看错,确实是1989年毕业的!),是一个生活在日本的美国人。

Brett一直默默无闻,直到他推出了HikariCP。

Hikari在日语中是“光”的意思,也就是说,这个连接池速度像“光”一样快。

HikariCP确实很快,在性能上碾压C3P0,DBCP2, Tomcat JDBC Pool 等一众连接池:

有了HikariCP这样耀眼的明星,就连BoneCP这样已经很快的连接池都不再维护了,它的作者“哀伤”说:BoneCP曾经击败过C3P0,DBCP这些老旧的连接池,但是为了支持HikariCP,可以放弃BoneCP了

现在已经有很多公司在使用HikariCP了,HikariCP还成为了SpringBoot默认的连接池,伴随着SpringBoot和微服务,HikariCP 必将迎来广泛的普及。

2

HikariCP 是怎么来的呢?

多年前,Brett 在开发一个产品原型,需要一个数据库连接池,像大多数开发人员一样,他Google了一个最流行的、最活跃的开源连接池。

很不幸的是,在对原型产品做压力测试的时候,他遇到了死锁问题,一些Exception表明线程之间的连接状态丢失了。

连接池是开源的,Brett把代码下载下来,试图找到并且Fix这些问题,然后贡献给社区。

但是当他开始阅读的时候,他发现这个连接池有几千行代码,远远超过他的预料。更要命的是有很多嵌套的锁,在一个地方获取,在很远的地方释放。在这样混乱的代码中,即使Fix了他遇到的问题,还有很多隐藏的问题难以预料。

Brett换了一个连接池并且检查了代码,这次加锁的语义清晰了,但是代码量依然比他期待的多两倍,尤其是在把核心的连接池逻辑委托给另外一个库的情况下!

Brett研究了更多的连接池,他发现这些连接池都以各种各样的方式违反了JDBC的规范和约定,例如当连接关闭,清除警告,回滚事务时,它们不会关闭Statements,不会重置用户更改的属性(如隔离级别),从而导致下一个消费者获得“脏连接”。

他不仅“仰天长叹”:这是真的吗?这就是Java发展20年后,连接池的现状吗?

程序员就是这样,遇到不爽的代码,还不如自己卷起袖子自己作一个, Talk is cheap ,show me the code !

这个连接池就是HikariCP,极致的性能让它拥有了良好的口碑,受到了越来越多用户的欢迎。

3

为什么HikariCP能这么快呢? 这要归功于Brett把事情做到极致的思路。

Brett深入到了字节码级别,他研究了程序编译出的字节码,甚至JIT编译出的汇编,以便使得关键的代码例程小于JIT内联阈值,他简化了继承层次结构,隐藏了成员变量,消除了强制类型转换。

他还做了很多微优化,其中一个就是不使用ArrayList,而是自己实现了一个叫FastList的类。因为ArrayList的get(int index)方法会对index做范围检查,而在HikariCP中,是可以确保index是合法的,范围检查是不必要的。

另外ArrayList 的remove(Object)方法会执行一个从头到尾的扫描,实际上JDBC的编程实践中在使用完Statement以后会马上关闭,或者以打开的相反次序来关闭,在这种情况下,从尾部扫描更好,于是ArrayList<Statement>被替换为自定义类FastList,这样就消除了这些额外开销。

HikariCP 还提供了一个自定义的无锁的ConcurrentBag,实现了高度的并发和极端的低延迟。

HikariCP 使用Javassist来生成Connection, Statement,和ResultSet的代理,在字节码中有getstatic 和invokevirtual 这样的指令,经过代码优化,它们被替换成了invokestatic ,这个指令更便于JVM去做更底层的优化。

这个优化甚至把栈帧中的栈深度从5降到了4,减少了push和pop指令

你看看,Brett可真是“锱铢必较”,榨干了每一个字节,这种精神好像在上世纪80年代,做DOS开发的程序员才可能拥有(Brett正好是89年毕业的),现在有了大容量的内存,更快的CPU,富裕了之后,大家已经忘记了曾经的窘境了。

正是这样一点点微小的优化,凝聚溪流,汇集成河,让HikariCP获得了“光速的”性能,让人佩服,我估计后来者很难超越了吧。

参考资料:

Jooq对Brett的采访:

https://dzone.com/articles/jooq-tuesdays-what-it-takes-to-write-the-fastest-java-connection-pool

https://www.linkedin.com/in/brett-wooldridge-b6181b/

https://github.com/brettwooldridge/HikariCP-benchmark

https://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole

https://github.com/brettwooldridge/HikariCP/issues/232

往期精彩回顾

我是一个线程

我是一个Java Class

面向对象圣经

函数式编程圣经

TCP/IP之大明邮差

CPU阿甘

我是一个网卡

我是一个路由器

一个故事讲完HTTPs

编程语言的巅峰

Java:一个帝国的诞生

JavaScript:一个屌丝的逆袭

负载均衡的原理

为什么HikariCP是性能最好的数据库连接池?相关推荐

  1. java 革命_JAVA数据库连接池的革命 -- 从BoneCP到HikariCP(转)

    从BoneCP到HikariCP 今天笔者本想更新一下项目中使用到的BoneCP版本的.却无意发现jolbox网站打不开了.起初以为是被墙掉了,经过一番查找,居然在BoneCP的Github站看到了如 ...

  2. SpringBoot 默认数据库连接池 HikariCP

    目录 引言 1.问题描述 2.SpringBoot默认的数据库连接池 3.HikariCP是什么 4.测试依赖 5.配置文件 5.1.数据库连接参数 5.2.连接池数据基本参数 5.3.连接检查参数 ...

  3. hikaricp 连接池分析_SpringBoot 2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...

  4. SpringBoot 2.0 中 HikariCP 数据库连接池原理解析

    作为后台服务开发,在日常工作中我们天天都在跟数据库打交道,一直在进行各种CRUD操作,都会使用到数据库连接池.按照发展历程,业界知名的数据库连接池有以下几种:c3p0.DBCP.Tomcat JDBC ...

  5. java 连接池_初探数据库连接池

    参考资料 数据库连接池学习笔记(一):原理介绍+常用连接池介绍 java数据库连接池实现原理 高性能数据库连接池的内幕 1. 为什么要使用连接池 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户 ...

  6. Spring Boot 数据库连接池入门

    本文在提供完整代码示例,可见 https://github.com/YunaiV/SpringBoot-Labs 的 lab-19 目录. 原创不易,给点个 Star 嘿,一起冲鸭! 1. 概述 在我 ...

  7. 数据库连接池原理及常用连接池介绍

    一.背景介绍 1.1 什么是连接池 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个. 1.2 为什么要使用连接池 数据库连接是一种关键的有 ...

  8. 一文搞定数据库连接池,太TM简单了,收藏!!!

    点赞再看,养成习惯 今天继续Java的课题,两天没有做任何事情,过了个自在的周末,但是不知道为什么总是有点淡淡的忧桑. 之前游戏服务器的数据源使用的是阿里巴巴的Druid,今天就大概说说数据源,给个实 ...

  9. 数据库连接池学习笔记(一):原理介绍+常用连接池介绍

    什么是连接池 数据库连接池负责分配.管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个. 为什么要使用连接池 数据库连接是一种关键的有限的昂贵的资源,这一点在多用户 ...

最新文章

  1. java 模拟时钟_java模拟时钟
  2. 近期活动盘点:数据科学研究院论坛“人文社科专场、全球最大的免费编程社区公开课、DeeCamp2019:实战AI 铸造定雨神针...
  3. chrome取消安全模式
  4. centos7安装mongodb详解
  5. android 自定义正方形 绕中心点旋转
  6. 【CentOS 7笔记24】,实验中发生的磁盘小故障#
  7. uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程
  8. post postman 传递数组对象_PostMan Post方式传递数组数据参数 OK_go
  9. Java架构经验总结
  10. java定义一个方法,返回整数数组的元素最大值
  11. devops_您无法购买DevOps
  12. 蔚来宣布再次完成1亿美元可转债融资
  13. 空间闹钟-v1.6更新!
  14. android webview 百度地图,Android WebView显示地图
  15. QCC512x QCC302x PIO 按键
  16. 修改oracle管理员用户密码
  17. @【基础测绘计算】(坐标正反算)
  18. CSS3基础(4)——CSS3 渲染属性
  19. php excel扩展名,excel后缀名是什么
  20. 2019年杭电多校第一场 1001题blank(DP)HDU6578

热门文章

  1. 地图数据--GeoJSON介绍
  2. C++websocket使用总结
  3. 机器学习、深度学习、强化学习
  4. 过滤器实现单一用户登录
  5. 贷款报单管理系统开发-集贷前审核、贷中管理、贷后催款、逾期预警等多位于一体
  6. cpu并行和gpu并行_GPU并行架构及渲染优化
  7. Modulo (mathematics)
  8. dnf跨几服务器比较稳定,DNF极具特色的几个跨区,跨6知名度最高,这个跨区打团不用挤频道...
  9. python xlsx 样式 谷歌开源 样式_连续加班一周最终把所有的Python库整理出来了,愿各位早日学会Py-站长资讯中心...
  10. 相遇倾城色,你若离亦不弃