侧边栏壁纸
  • 累计撰写 793 篇文章
  • 累计创建 1 个标签
  • 累计收到 1 条评论
标签搜索

目 录CONTENT

文章目录

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

Dettan
2021-07-10 / 0 评论 / 0 点赞 / 156 阅读 / 1,471 字
温馨提示:
本文最后更新于 2022-07-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

这世界上已经有了这么多的、开源的数据库连接池, 为什么要再写一个?
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
0

评论区