- HikariCP數據庫連接池實戰
- 朱政科
- 2836字
- 2019-09-02 17:55:06
3.1 Hikari背景、特色及前景
在HikariCP GitHub官網上寫著圖靈獎獲獎者Dijkstra的一句話:“Simplicity is prerequisite for reliability”,翻譯成中文大意是“簡單是可靠性的先決條件”。HikariCP在致敬前輩的同時,也真正做到了簡單、極致。其官網首頁的定義是:Fast, simple, reliable. HikariCP is a “zero-overhead” production ready JDBC connection pool. At roughly 130Kb, the library is very light.翻譯成中文的意思就是:快速,簡單,可靠。HikariCP是一個“零開銷”的JDBC連接池產品。它的庫非常輕量級,大約130Kb。
Hikari日語發音是Hi-ka-li(里),其作者在GitHub首頁及作者Wooldridge的采訪中都詳細提到了其正確的發音:
I've lived and worked in Tokyo since 2008, though I think my Japanese is far behind where it should be given my time here. I chalk that up to preferring time at the keyboard to language study.
【譯】自2008年以來,我一直在東京生活和工作,但我認為我的日語水平遠遠落后于我曾在這里待的時間。我認為比起語言學習,我更喜歡在鍵盤前學習。
As you mentioned, Hikari (pronounced Hi-ka-lee) translates to “Light” (as in sunlight). In English, it is a double entendre in the context of HikariCP; though in Japanese it would not be.“Light” in the sense of “the speed of…”, and “light” in the sense of being light in terms of code weight.
【譯】正如你(采訪記者)提到的,Hikari(發音為Hi-ka-lee)翻譯成“光”(在陽光下)。在英語中,HikariCP在語境中是雙關語;但是在日語中并不是這樣的。“光”的意思是“…的速度”, “光”的意思是代碼量很小。
Hikari雖然是日語,但是其作者卻是一個從2008年一直生活在日本東京的地道的美國人。Hikari的意思是光,HikariCP的意思是Hikari Connection Pool,就是Hikari連接池。從以上作者的描述中可以看到,作者之所以取這個名字是按照英文的語境給這款連接池賦予了兩個意義:速度快、代碼量小。從這個名字就可以看出,HikariCP的特色和優勢就是快。
小竅門
IDEA開發工具的Translation插件,可以聽到單詞的語音和某些技術詞匯的原產地,比如redis是意大利語,lombok是印尼語,Hikari是日語。
HikariCP的出現的背景來源于BoneCP。在BoneCP官網上的Readme中只有簡單的一段“遺言”,說了一段歷史,如圖3-1所示。翻譯成中文的意思就是:“BoneCP是一種Java JDBC連接池實現,通過最小化鎖爭來為應用程序提供更高的吞吐量,從而實現高性能。它擊敗了較舊的連接池,如C3P0和DBCP,但現在應該被視為棄用,以支持HikariCP。”

圖3-1 BoneCP官網上的Readme
HikariCP到底是何方神圣,竟能讓曾經叱咤風云的數據庫連接池開源產品放棄更新后“白帝托孤”?我們看一下HikariCP作者Brett Wooldridge在2017年2月21日的專欄中公布的其訪談文章。這篇文章中提供了一些HikariCP不為人知的背景故事,其中就包括HikariCP的創建初衷。
小知識
國外有一個專欄叫做jOOQ Tuesdays series,該專欄在每個月的第3個星期二會發布一篇在IT行業中令人興奮的人的訪談文章。采訪人員包括那些使用SQL、Java、開源軟件和各種其他相關主題的人員。
多年以前,Brett Wooldridge為其工作的公司創建了一個產品原型,當時,Brett Wooldridge需要一個數據庫連接池。和大多數開發者一樣,作者只想使用數據庫連接池,然后繼續他的工作,因此他在網上找到了最受歡迎的庫。不幸的是,在對原型進行負載測試時,他所在的技術團隊開始遇到死鎖,并且異常表明線程之間的連接狀態丟失了。
因為數據庫連接池是開源的,所以他認為只需要下載源代碼,找到并且修復問題,然后貢獻給社區即可(其實這也是大多數人使用開源項目的方式,先能夠用起來,遇到坑了,研究,然后修復,貢獻給社區)。不過當Brett Wooldridge打開這款數據庫連接池源碼的時候,他卻發現這個小小的數據庫連接池居然有上千行代碼,遠遠超過他的預料。另外,代碼中充斥了大量的鎖和嵌套,一些資源在一個方法中被請求卻在另一個遙遠的地方被釋放。這樣混亂的代碼,即使發現并修復了遇到的問題,也根本無法推斷潛在的問題的潛伏的地方。
Brett Wooldridge又換了一個開源的連接池并且檢查了它的代碼。鎖語義更清晰,但代碼量仍然是他預料的2倍,特別不能容忍的是這款開源代碼將核心連接池邏輯委托給一個單獨的庫。
此外,Brett Wooldridge研究的所有池都以多種方式違反了JDBC規約。在盡可能的情況下,連接池應該返回一個連接connection,該連接connection和連接池已經釋放的連接connection應該是無法區分的。但是,當連接關閉或者返回,或者清除警告,或者回滾未提交的事務時,這些連接池并不會自動關閉語句Statements。并且它們不會重置用戶更改的屬性,如自動提交或事務隔離級別,以及更多的一些參數,從而導致下一個消費者獲得將“臟”連接。
于是Brett Wooldridge就想:“真的嗎?難道這就是Java 20年后生態系統中連接池的狀態?”出于挫敗感和必要性,Brett Wooldridge創建了HikariCP。
很多連接池都是可以直接使用的,那么是什么理由使HikariCP脫穎而出呢?正確性和可靠性是很難出亮點的方向,所以Brett Wooldridge就專注于性能,并從一個簡單的推文開始逐漸分享他的數據庫連接池之旅。這樣的影響就像滾雪球一樣越來越大,一些用戶在推特上發布了關于HikariCP性能提升和可靠性提升的信息,并且在2015年的某個時候,Wix工程團隊寫了一篇關于切換到連接池HikariCP的博客。
從本質上來說,性能極致的口碑使得HikariCP越來越受歡迎,這也是大多數用戶推崇HikariCP的出發點。但是Brett Wooldridge還是非常希望隨著時間的推移,更多的用戶會同樣重視正確性和可靠性,否則性能就毫無意義,而HikariCP確實也做了很多與正確性和可靠性相關的工作。
在追求極致方面,Brett Wooldridge嘗試了一系列的優化,這些優化不是低級的代碼優化,而是包含算法優化以外一些更為極致的事情。Brett Wooldridge以基準測試benchmarks作為參照工具,研究了JMH微基準框架,他發現JVM執行了一系列驚人的優化,如果一個人不小心,那么在代碼中看起來很聰明的優化只會混淆JIT基于模式的優化器,結果反而會慢而不是更快。為了有效地優化JVM,除了JIT之外,還必須了解Java內存模型(JMM),以及它如何映射到x86等CPU架構。他閱讀了JIT源代碼,并且熟悉諸如死代碼消除、循環不變提升、常量傳播、虛擬調用內聯等概念。共享狀態的競爭是大多數瓶頸的根源(參見前面提到的JMM),所以最近最大的性能提升(例如,在v2.6.0中)來自于簡單地避免它的技巧,這些信息在本書后續章節都會介紹,希望對讀者進行中間件的調優有所幫助。
開發一款開源產品,Brett Wooldridge也會得到了很多用戶關于產品這樣或那樣的功能性需求,雖然每個要求都可能很簡單,但如果全部采納會顯著增加復雜性和代碼大小,而他的初衷還是希望數據庫連接池HikariCP足夠簡單。這點是大家需要注意的,就是Brett Wooldridge很可能會拒絕用戶的一些擴展性需求,因為他追求的是一條大道至簡的路。比如連接讀寫分離這樣的邏輯路由需求就不在HikariCP的未來規劃路線圖中,Brett Wooldridge傾向于認為這些更多的是Spring層應該去做的行為,而并不屬于數據庫連接池技術的范疇。
當然,這并不是說Brett Wooldridge不會添加新功能,不去更新HikariCP,相反,HikariCP至少在近幾年內的更新升級是比較頻繁的。比如,HikariCP的配置,作者認為配置的選項和維度越多,用戶就越難以優化配置池。但是,最終有足夠的用戶需要動態調整大小,并且缺少這種用戶是采用的障礙,因此增加了這方面的支持。原則上,他不希望因缺乏動態的大小支持而剝奪用戶對HikariCP的可靠性和正確性的認可。
Brett Wooldridge可能拒絕絕大多數功能要求,我們翻看GitHub上的文章就能看到作者拒絕了很多功能請求。作為HikariCP的監護人,保持簡單和真實的核心理念符合社區的最佳利益。在代碼和配置方面,Brett Wooldridge總是盡量減少“表面積”(通常,對于HikariCP的用戶而言,“表面積”表示配置參數的數量)。API的表面積越大,理解起來就越困難。
HikariCP的應用前景和未來發展也是非常可觀的。SpringBoot 2.x已經官方宣布使用HikariCP作為SpringBoot默認的數據庫連接池,隨著SpringBoot和微服務的蓬勃發展,HikariCP在全球范圍內的使用一定也會更加普及。
- Learning Cython Programming
- SpringMVC+MyBatis快速開發與項目實戰
- JMeter 性能測試實戰(第2版)
- 程序員考試案例梳理、真題透解與強化訓練
- Learning Firefox OS Application Development
- Easy Web Development with WaveMaker
- Android程序設計基礎
- 基于Struts、Hibernate、Spring架構的Web應用開發
- Instant Lucene.NET
- Python深度學習原理、算法與案例
- 監控的藝術:云原生時代的監控框架
- 零基礎C#學習筆記
- Java EE程序設計與開發實踐教程
- 數據庫技術及應用教程上機指導與習題(第2版)
- Mastering Unity 2017 Game Development with C#(Second Edition)