http://www.kuqin.com/system-analysis/20080704/10403.html
JBoss Cache是針對(duì)Java應(yīng)用的企業(yè)級(jí)集群解決方案,其目的是通過緩存需要頻繁訪問的Java對(duì)象,提高應(yīng)用的可用性并大幅度提升應(yīng)用的整體性能。InfoQ編輯就此對(duì)該項(xiàng)目的領(lǐng)頭人Manik Surtani做了一次專訪。
Manik,您能否首先跟大家講一下在您所接觸或者了解的客戶中,大部分人都是怎樣運(yùn)用JBoss Cache的?緩存能帶來哪些優(yōu)點(diǎn)?尤其是在高度的可用性方面,緩存帶來了怎樣的進(jìn)步?
從持續(xù)存儲(chǔ)、尤其是數(shù)據(jù)庫中讀取數(shù)據(jù)需要付出昂貴的代價(jià)。而且,數(shù)據(jù)庫在伸縮性方面也是臭名昭著(或者不便宜),當(dāng)你想要擴(kuò)展前端或增加更多客戶端時(shí),這個(gè)弊端顯然就成了障礙。另一方面,CPU和內(nèi)存的價(jià)格越來越便宜,這意味著更多的人可以負(fù)擔(dān)得起架設(shè)高可用系統(tǒng)所需的成本。“本站正在維護(hù)中”的暫停服務(wù)方式都應(yīng)當(dāng)成為歷史。
像JBoss Cache這樣的分布式緩存扮演的是一個(gè)處于應(yīng)用服務(wù)前端和數(shù)據(jù)庫間的中間層的角色,提供對(duì)持久性數(shù)據(jù)狀態(tài)在內(nèi)存中的快速訪問。JBoss Cache能夠確保緩存中的數(shù)據(jù)狀態(tài)和數(shù)據(jù)庫中的狀態(tài)一致、及時(shí)更新數(shù)據(jù)狀態(tài)、并且保證JVM不會(huì)出現(xiàn)堆溢出問題。
JBoss Cache和其它一些開源項(xiàng)目,例如Hibernate和JBoss Seam等的集成情況怎樣?
一些開源項(xiàng)目確實(shí)用到了JBoss Cache。Hibernate(以及JBoss Application Server的EJB3實(shí)現(xiàn))使用JBoss Cache來存儲(chǔ)從數(shù)據(jù)庫后端讀取的實(shí)體數(shù)據(jù),這樣一來在調(diào)用實(shí)體時(shí)就不需要每次都連接到數(shù)據(jù)庫去查找。我這樣說純粹只是一個(gè)簡(jiǎn)單的概括,Hibernate運(yùn)用分布式緩存的實(shí)際操作其實(shí)更復(fù)雜。
Seam也通過分布式緩存來緩存生成JSF頁面元素,從而改善那些頁面或者頁面元素生成速度比較緩慢的站點(diǎn)的伸縮性。
另外還有一些開源項(xiàng)目,如Lucene、Hibernate Search、GridGain、JBoss應(yīng)用服務(wù)器的HTTP Session集群和集群的單點(diǎn)登錄(Single Sign-On)代碼等都用到了JBoss Cache。
JBoss Cache提供兩種緩存方式:核心緩存和POJO緩存。您是否能給我們概括一下這兩者主要區(qū)別在哪里?
核心緩存會(huì)直接把您傳遞給它的數(shù)據(jù)存儲(chǔ)在一個(gè)樹型結(jié)構(gòu)中。鍵/值對(duì)被存儲(chǔ)在樹的節(jié)點(diǎn)上,出于復(fù)制或持續(xù)性的需要它們都被序列化了。
POJO緩存則采用比較復(fù)雜的機(jī)制——利用字節(jié)碼編織來內(nèi)省(introspecting)用戶類,并向用戶類的域添加偵聽器,一旦域值有任何變化,偵聽器會(huì)立刻通知緩存。例如,如果要在POJO緩存中存儲(chǔ)一個(gè)龐大、復(fù)雜的對(duì)象,會(huì)導(dǎo)致POJO緩存內(nèi)省對(duì)象的字節(jié)碼,最終只把該對(duì)象的原始域存儲(chǔ)到樹結(jié)構(gòu)中。一旦域值有所變化,緩存只復(fù)制這個(gè)改變了的域值而不會(huì)去復(fù)制整個(gè)用戶類,這是高效的細(xì)粒度復(fù)制。
當(dāng)然還有一些其它的不同之處,但最主要的區(qū)別還是我剛才講的。
細(xì)粒度復(fù)制定然會(huì)導(dǎo)致POJO緩存和核心緩存間在性能方面巨大的差異。您有沒有對(duì)兩者之間差異做過評(píng)估呢?
這類評(píng)估很大程度上決定于系統(tǒng)配置,如果只是做一般評(píng)估沒多大意義。在緩存面對(duì)龐大、復(fù)雜的對(duì)象的時(shí)候,細(xì)粒度復(fù)制確實(shí)有助于提高性能。但如果只是用它來存儲(chǔ)一些String的話,細(xì)粒度復(fù)制就沒有什么特別價(jià)值。類似地,對(duì)簡(jiǎn)單的用戶對(duì)象運(yùn)用POJO緩存——比方說一個(gè)只擁有兩個(gè)String域的Person類,與其說對(duì)性能有什么幫助,倒不如說它是浪費(fèi)開銷。
這就是為什么我一直建議大家依賴于用例編寫基準(zhǔn)測(cè)試來做比較。我們開發(fā)了一個(gè)框架在不同緩存和不同配置情況下進(jìn)行基準(zhǔn)測(cè)試——開發(fā)這個(gè)框架主要還是為了方便我們內(nèi)部比較不同版本的JBoss Cache之間的差異——但我們也提供該框架的下載,大家可以對(duì)它進(jìn)行擴(kuò)展,使用自定義的對(duì)象類型和訪問模式來重新編寫自定義測(cè)試。
你們?nèi)绾喂芾硪猛暾裕╮eferential integrity),尤其是POJO緩存?
如果你指的是對(duì)象的引用,那你剛好點(diǎn)到了之所以引進(jìn)字節(jié)碼編織的原因。我們針對(duì)POJO添加了攔截器并在緩存內(nèi)容中插入了引用域。
對(duì)于用戶來說,為什么要選擇本地緩存,而不用HashMap呢?
很多人認(rèn)為Map是考慮緩存的出發(fā)點(diǎn)(實(shí)際上,JSR-107 JCACHE專家組曾經(jīng)在Map的基礎(chǔ)上擴(kuò)展實(shí)現(xiàn)javax.cache.Cache)。盡管Map非常適合用來存儲(chǔ)簡(jiǎn)單的鍵/值對(duì),在緩存必需的其它特性上,它就難免有點(diǎn)黔驢技窮,比如內(nèi)存管理(eviction)、鈍化(passivation)和持續(xù)性、細(xì)粒度鎖定模型(首先,HashMap根本不是線程安全的;而ConcurrentHashMap采用的鎖是粗粒度級(jí)的,它甚至不允許非阻塞用戶或多用戶從map中讀取數(shù)據(jù))等。而對(duì)于“合格的”緩存來說,它還需要具備一些“企業(yè)”特性,包括JTA兼容、附加偵聽器等功能。
Map雖然是個(gè)好的起點(diǎn),但如果需要實(shí)現(xiàn)或者管理我剛才提到的那些特性的話,選擇緩存還是要比Map來得更合適一些。
分布式緩存中采用哪種鎖定機(jī)制?和傳統(tǒng)數(shù)據(jù)庫中采用的是同一種機(jī)制嗎?
JBoss Cache采用傳統(tǒng)的悲觀鎖(pessimistic locking)的方式,樹結(jié)構(gòu)中的每個(gè)節(jié)點(diǎn)對(duì)應(yīng)一個(gè)鎖。這些鎖的隔離級(jí)別和數(shù)據(jù)庫實(shí)施的隔離級(jí)別相同,允許多用戶同時(shí)讀取數(shù)據(jù)。
我們也提供樂觀鎖定(optimistically lock)方式,這個(gè)方式則牽涉到數(shù)據(jù)版本、每個(gè)事務(wù)的副本維護(hù)、主要樹結(jié)構(gòu)提交的事務(wù)副本確認(rèn)等等。在樂觀鎖定方式下,需要承載大量的數(shù)據(jù)讀取請(qǐng)求的系統(tǒng)因此可以獲得高度并發(fā)性。那些請(qǐng)求讀取數(shù)據(jù)的用戶不會(huì)因?yàn)椴l(fā)數(shù)據(jù)庫寫入操作而受到阻塞。而且,樂觀鎖定方式還可以避免悲觀鎖定中有可能發(fā)生的死鎖。
我們攜帶多版本并發(fā)控制(Multi Versioned Concurrency Control--MVCC)功能的JBoss Cache 3.0.0正在發(fā)布階段,當(dāng)前的開發(fā)任務(wù)非常重。大部分?jǐn)?shù)據(jù)庫系統(tǒng)都用到了多版本并發(fā)控制這種鎖定方式,它為我們提供了最好的樂觀鎖定和悲觀鎖。由于我們的實(shí)現(xiàn)不會(huì)阻礙任何用戶讀取數(shù)據(jù),因此在數(shù)據(jù)訪問速度上較之前者也勝出百倍。在MVCC功能相對(duì)穩(wěn)定之后,我們希望能把它設(shè)置為JBoss Cache默認(rèn)的鎖定機(jī)制。
您能否談一下JGroups集成?
JBoss Cache用JGroups作為組通信類庫,用來偵測(cè)組成員和組建集群。我們也把JGroups作為一個(gè)信道,在其上我們實(shí)現(xiàn)了一個(gè)RPC機(jī)制與組中其它緩存進(jìn)行通訊。由于JGoups的應(yīng)用,JBoss Cache獲得了高度靈活性,并在網(wǎng)絡(luò)協(xié)議和調(diào)整方面也極具擴(kuò)展性。JBoss Cache因此還使得緩存能夠擺脫LAN集群的框框,能夠穿透防火墻的限制并組建WAN集群等。
可以脫離JBoss AS單獨(dú)使用緩存嗎?
當(dāng)然可以!很多人都誤認(rèn)為JBoss Cache一定得在JBoss App Server下才能使用,其實(shí)不然。JBoss Cache可以在獨(dú)立的Java程序中使用,也可以在GUI前端使用,還能在其它一些應(yīng)用服務(wù)器中使用。我們只是把它捆綁在JBoss App Server中發(fā)布而已。
失敗轉(zhuǎn)移的關(guān)鍵是把數(shù)據(jù)復(fù)制到多個(gè)節(jié)點(diǎn),在實(shí)際開發(fā)中有很多策略可供選擇來復(fù)制數(shù)據(jù)。JBoss Cache支持的是哪種復(fù)制模式呢?
目前,我們支持兩種方式——全局復(fù)制(total replication——TR)和buddy復(fù)制(buddy replication——BR)。全局復(fù)制將狀態(tài)復(fù)制給小組中的所有成員。這種方式能夠幫助成員間共享數(shù)據(jù)狀態(tài),保證在失敗轉(zhuǎn)移時(shí)可以轉(zhuǎn)移到小組中的任何一個(gè)成員,但它限制了系統(tǒng)的伸縮性。Buddy復(fù)制則挑選特定成員擔(dān)當(dāng)備份數(shù)據(jù)的責(zé)任,數(shù)據(jù)狀態(tài)相應(yīng)地只會(huì)復(fù)制到這些特定節(jié)點(diǎn)上。也就是說直接轉(zhuǎn)移到復(fù)制節(jié)點(diǎn)的失敗轉(zhuǎn)移效率非常高,但即使轉(zhuǎn)移到任何非復(fù)制節(jié)點(diǎn),失敗轉(zhuǎn)移也同樣都順利進(jìn)行,因?yàn)閿?shù)據(jù)狀態(tài)會(huì)根據(jù)請(qǐng)求轉(zhuǎn)移到相應(yīng)的節(jié)點(diǎn)。BR最好用于session密切相關(guān)(session affinity)的情況下,因?yàn)閿?shù)據(jù)狀態(tài)的代價(jià)可能很高,所以應(yīng)該盡量?jī)H僅在發(fā)生失敗轉(zhuǎn)移的時(shí)候調(diào)用它。
某些特定的構(gòu)架中,點(diǎn)對(duì)點(diǎn)的節(jié)點(diǎn)復(fù)制方式會(huì)影響到系統(tǒng)的伸縮性。JBoss Cache中有類似的問題存在嗎?
沒有。P2P網(wǎng)絡(luò)和小組通訊在使用LAN和IP多播的時(shí)候效率非常高,伸縮性很強(qiáng)。大多數(shù)現(xiàn)代網(wǎng)絡(luò)設(shè)施都支持IP多播。但P2P數(shù)據(jù)復(fù)制中,由于每個(gè)節(jié)點(diǎn)都擁有整個(gè)系統(tǒng)的數(shù)據(jù)狀態(tài),系統(tǒng)伸縮性因此受到影響。我下面會(huì)對(duì)全局復(fù)制稍加評(píng)論。基于前面提到的原因,我們建議用戶使用與session密切相關(guān)的buddy復(fù)制。
我們還在開發(fā)分區(qū)功能,這個(gè)功能能夠幫助我們?cè)诒WC伸縮性的前提下真正地把數(shù)據(jù)狀態(tài)發(fā)送到各個(gè)數(shù)據(jù)組,而且不需要與session密切相關(guān)(session affinity)。希望這個(gè)功能的推出能夠取代全局復(fù)制和buddy復(fù)制。
在緩存和集群方面,您對(duì)近期的發(fā)展?fàn)顩r有怎樣的期望?JBoss Cache將會(huì)如何去滿足新的用戶需求?
隨著硬件越來越便宜、CPU廠商在每塊芯片上放置越來越多的內(nèi)核,分布式緩存將會(huì)越來越重要。這無疑意味著需要更多的“虛擬”機(jī),意味著數(shù)據(jù)庫需要“竭盡全力”去管理高度的并發(fā)性,也意味著分布式緩存將會(huì)成為數(shù)據(jù)瓶頸(data bottleneck)最重要的解決方式之一。逐漸流行的數(shù)據(jù)網(wǎng)格和云計(jì)算也同樣會(huì)推動(dòng)分布式緩存的發(fā)展,無論是“云”還是網(wǎng)格的數(shù)據(jù)節(jié)點(diǎn)都需要訪問和共享數(shù)據(jù)。
分區(qū)和MVCC功能也將助JBoss Cache一臂之力,能夠把集群伸縮性提高一個(gè)數(shù)量級(jí)。
英文原文:Distributed Caching with JBoss Cache: Q&A with Manik Surtani
來自:http://www.infoq.com/cn/news/2008/06/jboss-cache-interview