為什麼HikariCP被號稱為效能最好的Java資料庫連接池,如何配置使用

來源:互聯網
上載者:User

標籤:hikaricp   資料庫連接池   效能   革命   java   

HiKariCP是資料庫連接池的一個後起之秀,號稱效能最好,可以完美地PK掉其他串連池。
原文地址:http://blog.csdn.net/clementad/article/details/46928621
官網:https://github.com/brettwooldridge/HikariCP
為何要使用HiKariCP?這要先從BoneCP說起:

什嗎?不是有C3P0/DBCP這些成熟的資料庫連接池嗎?一直用的好好的,為什麼又搞出一個BoneCP來?因為,傳說中BoneCP在快速這個特點上做到了極致,官方資料是C3P0等的25倍左右。不相信?其實我也不怎麼信。可是,有圖有真相啊(圖片來自BoneCP官網:http://jolbox.com/benchmarks.html):



而且,網上對於BoneCP是好評如潮啊,推薦的文章一搜一大堆。
然而,上Maven Repository網站(http://mvnrepository.com/artifact/com.jolbox/bonecp)尋找有沒有最新版本的時候,你會發現最新的是2013年10月份的(這麼久沒新版本出來了?)。於是,再去BoneCP的Githut(https://github.com/wwadge/bonecp)上看看最近有沒有提交代碼。卻發現,BoneCP的作者對於這個項目貌似已經心灰意冷,說是要讓步給HikariCP了(有圖有真相):


……什嗎?又來一個CP?……什麼是Hikari?
Hikari來自日文,是“光”( 陽光的光,不是光禿禿的光)的意思。作者估計是為了藉助這個詞來暗示這個CP速度飛快。不知作者是不是日本人,不過日本也有很多優秀的碼農,聽說比特幣據說日本人搞出來的。。。
這個產品的口號是“快速、簡單、可靠”。實際情況跟這個口號真的匹配嗎?又是有圖有真相(Benchmarks又來了):


這個圖,也間接地、再一次地證明了boneCP比c3p0強大很多,當然,跟“光”比起來,又弱了不少啊。
那麼,這麼好的P是怎麼做到的呢?官網詳細地說明了HikariCP所做的一些最佳化,總結如下:
  • 位元組碼精簡:最佳化代碼,直到編譯後的位元組碼最少,這樣,CPU緩衝可以載入更多的程式碼;
  • 最佳化代理和攔截器:減少代碼,例如HikariCP的Statement proxy只有100行代碼,只有BoneCP的十分之一;
  • 自訂數群組類型(FastStatementList)代替ArrayList:避免每次get()調用都要進行range check,避免調用remove()時的從頭到尾的掃描;
  • 自訂集合類型(ConcurrentBag):提高並發讀寫的效率;
  • 其他針對BoneCP缺陷的最佳化,比如對於耗時超過一個CPU時間片的方法調用的研究(但沒說具體怎麼最佳化)。
很多最佳化的對比都是針對BoneCP的……哈哈。(參考文章:https://github.com/brettwooldridge/HikariCP/wiki/Down-the-Rabbit-Hole)
幾個串連池的代碼量對比(代碼量越少,一般意味著執行效率越高、發生bug的可能性越低):


可是,“黃婆賣瓜,自催自擂”這個俗語日本人也是懂得,於是,使用者的好評如潮也是有圖有真相:

還有第三方關於速度的測試:

也許你會說,速度高,如果不穩定也是硬傷啊。於是,關於穩定性的圖也來了:

另外,關於可靠性方面,也是有實驗和資料支援的。對於資料庫連接中斷的情況,通過測試getConnection(),各種CP的不相同處理方法如下:(所有CP都配置了跟connectionTimeout類似的參數為5秒鐘) HikariCP:等待5秒鐘後,如果串連還是沒有恢複,則拋出一個SQLExceptions 異常;後續的getConnection()也是一樣處理; C3P0:完全沒有反應,沒有提示,也不會在“CheckoutTimeout”配置的時間長度逾時後有任何通知給調用者;然後等待2分鐘後終於醒來了,返回一個error; Tomcat:返回一個connection,然後……調用者如果利用這個無效的connection執行SQL語句……結果可想而知;大約55秒之後終於醒來了,這時候的getConnection()終於可以返回一個error,但沒有等待參數配置的5秒鐘,而是立即返回error; BoneCP:跟Tomcat的處理方法一樣;也是大約55秒之後才醒來,有了正常的反應,並且終於會等待5秒鐘之後返回error了;
可見,HikariCP的處理方式是最合理的。根據這個測試結果,對於各個CP處理資料庫中斷的情況,評分如下:

參考文章:https://github.com/brettwooldridge/HikariCP/wiki/Bad-Behavior:-Handling-Database-Down

說得這麼好,用起來會不會很麻煩啊,會不會有很多參數要配置才能有這樣的效果啊?答案是:不會。如果之前用的是BoneCP配置的資料來源,那麼,就簡單了,只需要把dataSource換一下,稍微調整一下參數就行了:
BoneCP的資料來源配置:
 <!-- BoneCp Datasource --> <bean id="dataSourceBoneCp" class="com.jolbox.bonecp.BoneCPDataSource" destroy-method="close">  <property name="driverClass" value="${db.driverClass}" />  <property name="jdbcUrl" value="${db.url}" />  <property name="username" value="${db.username}" />  <property name="password" value="${db.password}" />  <property name="idleConnectionTestPeriodInMinutes" value="2" />  <property name="idleMaxAgeInMinutes" value="2" />  <property name="maxConnectionsPerPartition" value="2" />  <property name="minConnectionsPerPartition" value="0" />  <property name="partitionCount" value="2" />  <property name="acquireIncrement" value="1" />  <property name="statementsCacheSize" value="100" />  <property name="lazyInit" value="true"/>  <property name="maxConnectionAgeInSeconds" value="20"/>  <property name="defaultReadOnly" value="true"/> </bean>

HiKariCP的資料來源配置:
 <!-- Hikari Datasource --> <bean id="dataSourceHikari" class="com.zaxxer.hikari.HikariDataSource"  destroy-method="shutdown">  <!-- <property name="driverClassName" value="${db.driverClass}" /> --> <!-- 無需指定,除非系統無法自動識別 -->  <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8" />  <property name="username" value="${db.username}" />  <property name="password" value="${db.password}" />   <!-- 串連唯讀資料庫時配置為true, 保證安全 -->  <property name="readOnly" value="false" />  <!-- 等待串連池分配串連的最大時間長度(毫秒),超過這個時間長度還沒可用的串連則發生SQLException, 預設:30秒 -->  <property name="connectionTimeout" value="30000" />  <!-- 一個串連idle狀態的最大時間長度(毫秒),逾時則被釋放(retired),預設:10分鐘 -->  <property name="idleTimeout" value="600000" />  <!-- 一個串連的生命時間長度(毫秒),逾時而且沒被使用則被釋放(retired),預設:30分鐘,建議設定比資料庫逾時時間長度少30秒,參考MySQL wait_timeout參數(show variables like '%timeout%';) -->  <property name="maxLifetime" value="1800000" />  <!-- 串連池中允許的最大串連數。預設值:10;推薦的公式:((core_count * 2) + effective_spindle_count) -->  <property name="maximumPoolSize" value="15" /> </bean>

其中,很多配置都使用預設值就行了,除了maxLifetime和maximumPoolSize要注意自己計算一下。其他的配置(sqlSessionFactory、MyBatis MapperScannerConfigurer、transactionManager等)統統不用變。
其他關於Datasource配置參數的建議:Configure your HikariCP idleTimeout and maxLifeTime settings to be one minute less than the wait_timeout of MySQL.對於有Java串連池的系統,建議MySQL的wait_timeout使用預設的8小時(http://www.rackspace.com/knowledge_center/article/how-to-change-the-mysql-timeout-on-a-server)。
另外:對於web項目,記得要配置:destroy-method="shutdown"
(原創文章,轉載請註明轉自Clement-Xu的csdn部落格。)



著作權聲明:本文為原創文章,轉載請註明轉自Clement-Xu的csdn部落格。

為什麼HikariCP被號稱為效能最好的Java資料庫連接池,如何配置使用

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.