回覆列表
  • 1 # SapphireCoder

    建議可以瞭解一下HiKariCP。

    在實際開發中我們常所熟知的資料庫連線池有C3P0,DBCP、阿里Druid,等。但隨著Springboot 2.0選擇HikariCP作為預設資料庫連線池這一事件之後,HiKariCP作為一個後起之秀出現在大眾的視野中,以其速度快,效能高等特點受到很多人青睞。下面是我收集到的一些關於HikariCP的資料,用於幫助瞭解認識HiKariCP。

    什麼是HikariCP

    HikariCP是由日本程式設計師開源的一個數據庫連線池元件,是一個打著為“快速、簡單、可靠”口號的後起之秀。

    HikariCP優勢亮點在哪裡?

    1、高效能,圖中與其他資料庫連線池相比,HikariCP每秒的運算元遠大於其他資料庫連線池

    2、穩定,當切換為HikariCP連線池後更加穩定。

    3、程式碼量少

    那麼為什麼HikariCP會那麼快?位元組碼精簡,透過最佳化程式碼直到編譯後的位元組碼最少,使得CPU快取可以載入更多的程式程式碼。實現了一個無鎖的集合型別(ConcurrentBag),來減少併發造成的資源競爭。使用了自定義的陣列型別(FastList),相對與ArrayList極大地提升了效能。針對CPU的時間片演算法進行最佳化,儘可能在一個時間片裡面完成各種操作。

    位元組碼精簡

    HikariCP利用了一個第三方的Java位元組碼修改類庫Javassist來生成委託實現動態代理。透過使用Javassist生成動態代理,因為其速度更快且相比於JDK Proxy生成的位元組碼更少,使得CPU快取可以載入更多的程式程式碼。

    ConcurrentBag集合

    ConcurrentBag是一個專門為連線池設計的lock-less集合,實現了比LinkedBlockingQueue、LinkedTransferQueue更好的併發效能。ConcurrentBag內部同時使用了ThreadLocal和CopyOnWriteArrayList來儲存元素,其中CopyOnWriteArrayList是執行緒共享的。ConcurrentBag採用了queue-stealing的機制獲取元素:首先嚐試從ThreadLocal中獲取屬於當前執行緒的元素來避免鎖競爭,如果沒有可用元素則再次從共享的CopyOnWriteArrayList中獲取。此外,ThreadLocal和CopyOnWriteArrayList在ConcurrentBag中都是成員變數,執行緒間不共享,避免了偽共享(false sharing)的發生。

    FastList

    使用FastList替代ArrayListFastList是一個List介面的精簡實現,只實現了介面中必要的幾個方法。JDK ArrayList每次呼叫get()方法時都會進行rangeCheck檢查索引是否越界,FastList的實現中去除了這一檢查,只要保證索引合法那麼rangeCheck就成為了不必要的計算開銷(當然開銷極小)。此外,HikariCP使用List來儲存開啟的Statement,當Statement關閉或Connection關閉時需要將對應的Statement從List中移除。通常情況下,同一個Connection建立了多個Statement時,後開啟的Statement會先關閉。ArrayList的remove(Object)方法是從頭開始遍歷陣列,而FastList是從陣列的尾部開始遍歷,因此更為高效。

  • 2 # 寫程式設計師的程式碼

    說到連線池,就必須先知道什麼是連線池:

    一、連線池的工作原理主要由三部分組成,分別為

    1、連線池的建立

    2、連線池中連線的使用管理

    3、連線池的關閉

    二、連線池的主要引數

    最小連線數Min Pool Size: 預設為0。是連線池一直保持的資料庫連線,所以如果應用程式對資料庫連線的使用量不大,將會有大量的資料庫連線資源被浪費.

    最大連線數Max Pool Size: 預設為100。:是連線池能申請的最大連線數,如果資料庫連線請求超過次數,後面的資料庫連線請求將被加入到等待佇列中,這會影響以後的資料庫操作

    最大空閒時間

    獲取連線超時時間Connection Timeout:連線請求等待超時時間。預設為15秒,單位為秒。

    超時重試連線次數

    三、資料庫對比

    第一、二代連線池

    表格中可以看到,c3p0和dbcp等第一代基本已經死掉了,二代產品對一代產品的超越是顛覆性的,除了一些“歷史原因”,你很難再找到第二條理由說服自己不選擇二代產品,但任何成功都不是偶然的,二代產品的成功很大程度上得益於前代產品們打下的基礎,站在巨人的肩膀上,新一代的連線池的設計師們將這一項“工具化”的產品,推向了極致。其中,最具代表性的兩款產品是:

    HikariCP

    Druid效能無敵的HikariCP

    HikariCP號稱“效能殺手”(It’s Faster),

    那它是怎麼做到如此強勁的呢?官網給出的說明如下:

    位元組碼精簡:最佳化程式碼,直到編譯後的位元組碼最少,這樣,CPU快取可以載入更多的程式程式碼;

    最佳化代理和攔截器:減少程式碼,例如HikariCP的Statement proxy只有100行程式碼;

    自定義陣列型別(FastStatementList)代替ArrayList:避免每次get()呼叫都要進行range check,避免呼叫remove()時的從頭到尾的掃描;

    自定義集合型別(ConcurrentBag):提高併發讀寫的效率;

    其他缺陷的最佳化,比如對於耗時超過一個CPU時間片的方法呼叫的研究(但沒說具體怎麼最佳化)。

    可以看到,上述這幾點最佳化,和現在能找到的資料來看,HakariCP在效能上的優勢應該是得到共識的,再加上它自身小巧的身形,在當前的“雲時代、微服務”的背景下,HakariCP一定會得到更多人的青睞。功能全面的Druid

    相較於其他產品,Druid另一個比較大的優勢,就是中文文件比較全面(畢竟是華人的專案麼),在github的wiki頁面,列舉了日常使用中可能遇到的問題,對一個新使用者來講,上面提供的內容已經足夠指導它完成產品的配置和使用了。

    現在專案開發中,我還是比較傾向於使用Durid,它不僅僅是一個數據庫連線池,它還包含一個ProxyDriver,一系列內建的JDBC元件庫,一個SQL Parser,所以我們專案目前用的也是這個連線池。

    Druid 相對於其他資料庫連線池的優點

    強大的監控特性,透過Druid提供的監控功能,可以清楚知道連線池和SQL的工作情況。

    a. 監控SQL的執行時間、ResultSet持有時間、返回行數、更新行數、錯誤次數、錯誤堆疊資訊;

    b. SQL執行的耗時區間分佈。什麼是耗時區間分佈呢?比如說,某個SQL執行了1000次,其中0~1毫秒區間50次,1~10毫秒800次,10~100毫秒100次,100~1000毫秒30次,1~10秒15次,10秒以上5次。透過耗時區間分佈,能夠非常清楚知道SQL的執行耗時情況;

    c. 監控連線池的物理連線建立和銷燬次數、邏輯連線的申請和關閉次數、非空等待次數、PSCache命中率等。

    方便擴充套件。Druid提供了Filter-Chain模式的擴充套件API,可以自己編寫Filter攔截JDBC中的任何方法,可以在上面做任何事情,比如說效能監控、SQL審計、使用者名稱密碼加密、日誌等等。

    Druid集合了開源和商業資料庫連線池的優秀特性,並結合阿里巴巴大規模苛刻生產環境的使用經驗進行最佳化。

    綜上所述:效能方面hikariCP>driuddriud功能區最為全面,sql攔截等功能,統計資料較為全民,具有良好的擴充套件性。綜合性能,擴充套件方面,兩者都可以考慮。開啟prepareStatement快取,對效能會有20%提升。

    功能區對比:

    查詢一條語句對比:

  • 中秋節和大豐收的關聯?
  • 小說《平凡的世界》怎麼樣?