聊聊Java主流數據庫連接池優劣及未來

主流數據庫連接池

常用的主流開源數據庫連接池有C3P0、DBCP、Tomcat Jdbc Pool、BoneCP、Druid等

C3p0: 開源的JDBC連接池,實現了數據源和JNDI綁定,支持JDBC3規範和JDBC2的標準擴展。目前使用它的開源項目有Hibernate、Spring等。單線程,性能較差,適用於小型系統,代碼600KB左右。

DBCP (Database Connection Pool):由Apache開發的一個Java數據庫連接池項目, Jakarta commons-pool對象池機制,Tomcat使用的連接池組件就是DBCP。單獨使用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。

BoneCP:官方說法BoneCP是一個高效、免費、開源的Java數據庫連接池實現庫。設計初衷就是為了提高數據庫連接池性能,根據某些測試數據顯示,BoneCP的速度是最快的,要比當時第二快速的連接池快25倍左右,完美集成到一些持久化產品如Hibernate和DataNucleus中。BoneCP特色:高度可擴展,快速;連接狀態切換的回調機制;允許直接訪問連接;自動化重置能力;JMX支持;懶加載能力;支持XML和屬性文件配置方式;較好的Java代碼組織,100%單元測試分支代碼覆蓋率;代碼40KB左右。

Druid:Druid是Java語言中最好的數據庫連接池,Druid能夠提供強大的監控和擴展功能,是一個可用於大數據實時查詢和分析的高容錯、高性能的開源分佈式系統,尤其是當發生代碼部署、機器故障以及其他產品系統遇到宕機等情況時,Druid仍能夠保持100%正常運行。主要特色:為分析監控設計;快速的交互式查詢;高可用;可擴展;Druid是一個開源項目,源碼託管在github上。

主流連接池各項功能對比如下

聊聊Java主流數據庫連接池優劣及未來

Java數據庫連接池比較

我們再看一組有HikariCP的比較:

聊聊Java主流數據庫連接池優劣及未來

各色連接池比較

HikariCP性能分析:

  • HikariCP通過優化(concurrentBag,fastStatementList )集合來提高併發的讀寫效率。
  • HikariCP使用threadlocal緩存連接及大量使用CAS的機制,最大限度的避免lock。單可能帶來cpu使用率的上升。
  • 從字節碼的維度優化代碼。 (default inline threshold for a JVM running the server Hotspot compiler is 35 bytecodes )讓方法儘量在35個字節碼一下,來提升jvm的處理效率。

HikariCP做的優化補充如下:

聊聊Java主流數據庫連接池優劣及未來

優化補充說明

聊聊Java主流數據庫連接池優劣及未來

內聯描述

mysql connecter 源碼裡用的就是ping命令:

聊聊Java主流數據庫連接池優劣及未來

比HikariCP更快的數據庫連接池

一個同事告訴我,比hikari還快的連接池他也用過、研究過,

https://github.com/mauricio/postgresql-async

這是scala生態圈的東西。用netty實現了mysql協議,沒用mysql官方的connector,純異步的,它的連接池是寫的比較隨便,但是性能依然很好。

前瞻,未來到底是HikariCP還是Druid的天下?

很多人都在問,站在巨人肩膀上的第二代連接池HikariCP和druid到底孰強孰弱?其實我覺得這是一個不必討論的問題。

我們先來看看未來的趨勢:單機的操作系統將會被拋棄,取而代之的是容器調度加編排的雲操作系統。裸機或者虛擬機的運行時也將會被容器取代。通信方面將會使用Service Mesh。

也就是說中間件最後的趨勢一定是弱化到無感知,這才是最終的一個大道至簡的方向。那些maven依賴問題,把二方庫寫在pom裡,監控等代碼的硬編碼進應用裡都將逐漸弱化到不復存在,取而代之的那些java agent(如pinpoint、skywalking之類),抑或是service mesh這種side car模式都是可以做中間件(包括連接池)的監控的。

一個有讚的朋友告訴我,在有贊核心應用,用HikariCP替換durid後,RT出現斷崖式下滑(1.5ms ~ 1.2ms) 並且持續穩定毛刺少。性能測試與壓測之後,一核心系統與druid相比,性能提高一倍左右。

阿飛做了如下統計工作,都是基於最新tag統計的,只統計java文件和xml文件,druid(alibaba-druid)總行數:430289,HikariCP(brettwooldridge-HikariCP)總行數:18372。

只統計java代碼,druid(alibaba-druid)總行數:428749,HikariCP(brettwooldridge-HikariCP)總行數:17556。

再過濾一下test目錄,(alibaba-druid)總行數:215232,(brettwooldridge-HikariCP)總行數:7960。

光一個DruidDataSource就3000行,且不說性能,druid是在jdbc的基礎上,自己編碼做得增強。

如果這麼說,druid準確的說是生活在第一代和第二代連接池的面向過程的年代。druid可能忘了松耦合這個概念,把監控和數據庫連接池做在一個項目裡,本身就是緊耦合。既然微服務提倡業務隔離性,那麼這種難道不應該隔離麼?讓組件工具一次只做一件事不好麼?監控的事情在service mesh的將來畢竟是有別的其天然的監控手法的而不是硬編碼在一個小小的連接池裡。綜上所述,放在現在或是未來的趨勢去拼,大概率比不過擁抱springboot 2.0以及大道至簡精簡到極致的HikariCP。

未來的中間件,一定是和spring生態圈和servich mesh一樣,大道至簡,越來越薄,升級中間件不再是需要用戶強行升級maven依賴解決依賴衝突,而是通過mesh的方式極致到升級讓業務方無感知。所以那些熱部署、潘多拉boot、容器隔離等解決依賴衝突的妥協方式也將可能大概率被置換掉。

從Sharding-jdbc架構演進看未來

Database Mesh,一個搭乘 Service Mesh 浪潮衍生出來的新興詞彙。顧名思義,Database Mesh 使用一個齧合層,將散落在系統各個角落中的數據庫統一治理起來。通過齧合層集中在一起的應用與數據庫之間的交互網絡,就像蜘蛛網一樣複雜而有序。它的首要目標並非齧合存儲於數據庫中的數據,而是齧合應用與數據庫間的交互。

Database Mesh 的關注重點在於如何將分佈式的數據訪問應用與數據庫有機串聯起來,它更加關注的是交互,是將雜亂無章的應用與數據庫之間的交互有效的梳理。

使用 Database Mesh,訪問數據庫的應用和數據庫終將形成一個巨大的網格體系,應用和數據庫只需在網格體系中對號入座即可,它們都是被齧合層所治理的對象。

Sharding-JDBC 一直以來,以 JDBC 層分片作為其核心理念。它的架構圖如下:

聊聊Java主流數據庫連接池優劣及未來

Sharding-JDBC 將分別實現 Driver、Server 以及 Sidecar 這三個不同的版本,一起組成 Sharding-JDBC 的生態圈,為不同的需求與環境提供更加具有針對性的差異化服務。

聊聊Java主流數據庫連接池優劣及未來

由於 Sharding-JDBC-Server 的出現,使得原來 DBA 通過 Sharding-JDBC-Driver 無法對數據進行操作的缺憾得到了補償。由於 Sharding-JDBC-Driver 無需通過代理層進行二次轉發,因此線上性能更佳,可以通過以下的混合部署方案使用 Sharding-JDBC:

聊聊Java主流數據庫連接池優劣及未來

線上應用使用 Sharding-JDBC-Driver 直連數據庫以獲取最優性能,使用 MySQL 命令行或 UI 客戶端連接 Sharding-JDBC-Server 方便的查詢數據和執行各種 DDL 語句。它們使用同一個註冊中心集群,通過管理端配置註冊中心中的數據,即可由註冊中心自動將配置變更推送至 Driver 和 Server 應用。若數據庫拆分的過多而導致連接數會暴漲,則可以考慮直接在線上使用 Sharding-JDBC-Server,以達到有效控制連接數的目的。

在不久的將來,Sharding-JDBC-Sidecar 也將問世,它的部署架構是這樣的:

聊聊Java主流數據庫連接池優劣及未來

基於 Sharding-JDBC 的 Database Mesh 與 Service Mesh 互不干擾,相得益彰。服務之間的交互由 Service Mesh Sidecar 接管,基於 SQL 的數據庫訪問由 Sharding-JDBC-Sidecar 接管。

對於業務應用來說,無論是 RPC 還是對數據庫的訪問,都無需關注其真實的物理部署結構,做到真正的零侵入。由於 Sharding-JDBC-Sidecar 是隨著宿主機的生命週期創建和消亡的,

因此,它並非靜態 IP,而是完全動態和彈性的存在,整個系統中並無任何中心節點的存在。對於數據運維等操作,仍然可以通過啟動一個 Sharding-JDBC-Server 的進程作為靜態 IP 的入口,通過各種命令行或 UI 客戶端進行操作。

參考來源:https://mp.weixin.qq.com/s/aBeX307FI6vnw_DatqjC0g


分享到:


相關文章: