<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    午后星期午

    Ehcache詳細(xì)解讀

    Ehcache  是現(xiàn)在最流行的純Java開(kāi)源緩存框架,配置簡(jiǎn)單、結(jié)構(gòu)清晰、功能強(qiáng)大,最初知道它,是從Hibernate的緩存開(kāi)始的。網(wǎng)上中文的EhCache材料以簡(jiǎn)單介紹和配置方法居多,如果你有這方面的問(wèn)題,請(qǐng)自行g(shù)oogle;對(duì)于API,官網(wǎng)上介紹已經(jīng)非常清楚,請(qǐng)參見(jiàn)官網(wǎng);但是很少見(jiàn)到特性說(shuō)明和對(duì)實(shí)現(xiàn)原理的分析,因此在這篇文章里面,我會(huì)詳細(xì)介紹和分析EhCache的特性,加上一些自己的理解和思考,希望對(duì)緩存感興趣的朋友有所收獲。

     

    一、特性一覽 ,來(lái)自官網(wǎng),簡(jiǎn)單翻譯一下:

     

    1、快速輕量
    過(guò)去幾年,諸多測(cè)試表明Ehcache是最快的Java緩存之一。
    Ehcache的線程機(jī)制是為大型高并發(fā)系統(tǒng)設(shè)計(jì)的。
    大量性能測(cè)試用例保證Ehcache在不同版本間性能表現(xiàn)得一致性。
    很多用戶都不知道他們正在用Ehcache,因?yàn)椴恍枰裁刺貏e的配置。
    API易于使用,這就很容易部署上線和運(yùn)行。
    很小的jar包,Ehcache 2.2.3才668kb。
    最小的依賴:唯一的依賴就是SLF4J了。

    2、伸縮性
    緩存在內(nèi)存和磁盤存儲(chǔ)可以伸縮到數(shù)G,Ehcache為大數(shù)據(jù)存儲(chǔ)做過(guò)優(yōu)化。
    大內(nèi)存的情況下,所有進(jìn)程可以支持?jǐn)?shù)百G的吞吐。
    為高并發(fā)和大型多CPU服務(wù)器做優(yōu)化。
    線程安全和性能總是一對(duì)矛盾,Ehcache的線程機(jī)制設(shè)計(jì)采用了Doug Lea的想法來(lái)獲得較高的性能。
    單臺(tái)虛擬機(jī)上支持多緩存管理器。
    通過(guò)Terracotta服務(wù)器矩陣,可以伸縮到數(shù)百個(gè)節(jié)點(diǎn)。

    3、靈活性
    Ehcache 1.2具備對(duì)象API接口和可序列化API接口。
    不能序列化的對(duì)象可以使用除磁盤存儲(chǔ)外Ehcache的所有功能。
    除了元素的返回方法以外,API都是統(tǒng)一的。只有這兩個(gè)方法不一致:getObjectValue和getKeyValue。這就使得緩存對(duì)象、序列化對(duì)象來(lái)獲取新的特性這個(gè)過(guò)程很簡(jiǎn)單。
    支持基于Cache和基于Element的過(guò)期策略,每個(gè)Cache的存活時(shí)間都是可以設(shè)置和控制的。
    提供了LRU、LFU和FIFO緩存淘汰算法,Ehcache 1.2引入了最少使用和先進(jìn)先出緩存淘汰算法,構(gòu)成了完整的緩存淘汰算法。
    提供內(nèi)存和磁盤存儲(chǔ),Ehcache和大多數(shù)緩存解決方案一樣,提供高性能的內(nèi)存和磁盤存儲(chǔ)。
    動(dòng)態(tài)、運(yùn)行時(shí)緩存配置,存活時(shí)間、空閑時(shí)間、內(nèi)存和磁盤存放緩存的最大數(shù)目都是可以在運(yùn)行時(shí)修改的。

    4、標(biāo)準(zhǔn)支持
    Ehcache提供了對(duì)JSR107 JCACHE API最完整的實(shí)現(xiàn)。因?yàn)镴CACHE在發(fā)布以前,Ehcache的實(shí)現(xiàn)(如net.sf.jsr107cache)已經(jīng)發(fā)布了。
    實(shí)現(xiàn)JCACHE API有利于到未來(lái)其他緩存解決方案的可移植性。
    Ehcache的維護(hù)者Greg Luck,正是JSR107的專家委員會(huì)委員。

    5、可擴(kuò)展性
    監(jiān)聽(tīng)器可以插件化。Ehcache 1.2提供了CacheManagerEventListener和CacheEventListener接口,實(shí)現(xiàn)可以插件化,并且可以在ehcache.xml里配置。
    節(jié)點(diǎn)發(fā)現(xiàn),冗余器和監(jiān)聽(tīng)器都可以插件化。
    分布式緩存,從Ehcache 1.2開(kāi)始引入,包含了一些權(quán)衡的選項(xiàng)。Ehcache的團(tuán)隊(duì)相信沒(méi)有什么是萬(wàn)能的配置。
    實(shí)現(xiàn)者可以使用內(nèi)建的機(jī)制或者完全自己實(shí)現(xiàn),因?yàn)橛型暾牟寮_(kāi)發(fā)指南。
    緩存的可擴(kuò)展性可以插件化。創(chuàng)建你自己的緩存擴(kuò)展,它可以持有一個(gè)緩存的引用,并且綁定在緩存的生命周期內(nèi)。
    緩存加載器可以插件化。創(chuàng)建你自己的緩存加載器,可以使用一些異步方法來(lái)加載數(shù)據(jù)到緩存里面。
    緩存異常處理器可以插件化。創(chuàng)建一個(gè)異常處理器,在異常發(fā)生的時(shí)候,可以執(zhí)行某些特定操作。

    6、應(yīng)用持久化
    在VM重啟后,持久化到磁盤的存儲(chǔ)可以復(fù)原數(shù)據(jù)。
    Ehcache是第一個(gè)引入緩存數(shù)據(jù)持久化存儲(chǔ)的開(kāi)源Java緩存框架。緩存的數(shù)據(jù)可以在機(jī)器重啟后從磁盤上重新獲得。
    根據(jù)需要將緩存刷到磁盤。將緩存條目刷到磁盤的操作可以通過(guò)cache.flush()方法來(lái)執(zhí)行,這大大方便了Ehcache的使用。

    7、監(jiān)聽(tīng)器
    緩存管理器監(jiān)聽(tīng)器。允許注冊(cè)實(shí)現(xiàn)了CacheManagerEventListener接口的監(jiān)聽(tīng)器:
    notifyCacheAdded()
    notifyCacheRemoved()
    緩存事件監(jiān)聽(tīng)器。允許注冊(cè)實(shí)現(xiàn)了CacheEventListener接口的監(jiān)聽(tīng)器,它提供了許多對(duì)緩存事件發(fā)生后的處理機(jī)制:
    notifyElementRemoved/Put/Updated/Expired 

    8、開(kāi)啟JMX
    Ehcache的JMX功能是默認(rèn)開(kāi)啟的,你可以監(jiān)控和管理如下的MBean:
    CacheManager、Cache、CacheConfiguration、CacheStatistics 

    9、分布式緩存
    從Ehcache 1.2開(kāi)始,支持高性能的分布式緩存,兼具靈活性和擴(kuò)展性。
    分布式緩存的選項(xiàng)包括:
    通過(guò)Terracotta的緩存集群:設(shè)定和使用Terracotta模式的Ehcache緩存。緩存發(fā)現(xiàn)是自動(dòng)完成的,并且有很多選項(xiàng)可以用來(lái)調(diào)試緩存行為和性能。
    使用RMI、JGroups或者JMS來(lái)冗余緩存數(shù)據(jù):節(jié)點(diǎn)可以通過(guò)多播或發(fā)現(xiàn)者手動(dòng)配置。狀態(tài)更新可以通過(guò)RMI連接來(lái)異步或者同步完成。
    Custom:一個(gè)綜合的插件機(jī)制,支持發(fā)現(xiàn)和復(fù)制的能力。
    可用的緩存復(fù)制選項(xiàng)。支持的通過(guò)RMI、JGroups或JMS進(jìn)行的異步或同步的緩存復(fù)制。
    可靠的分發(fā):使用TCP的內(nèi)建分發(fā)機(jī)制。
    節(jié)點(diǎn)發(fā)現(xiàn):節(jié)點(diǎn)可以手動(dòng)配置或者使用多播自動(dòng)發(fā)現(xiàn),并且可以自動(dòng)添加和移除節(jié)點(diǎn)。對(duì)于多播阻塞的情況下,手動(dòng)配置可以很好地控制。
    分布式緩存可以任意時(shí)間加入或者離開(kāi)集群。緩存可以配置在初始化的時(shí)候執(zhí)行引導(dǎo)程序員。
    BootstrapCacheLoaderFactory抽象工廠,實(shí)現(xiàn)了BootstrapCacheLoader接口(RMI實(shí)現(xiàn))。
    緩存服務(wù)端。Ehcache提供了一個(gè)Cache Server,一個(gè)war包,為絕大多數(shù)web容器或者是獨(dú)立的服務(wù)器提供支持。
    緩存服務(wù)端有兩組API:面向資源的RESTful,還有就是SOAP。客戶端沒(méi)有實(shí)現(xiàn)語(yǔ)言的限制。
    RESTful緩存服務(wù)器:Ehcached的實(shí)現(xiàn)嚴(yán)格遵循RESTful面向資源的架構(gòu)風(fēng)格。
    SOAP緩存服務(wù)端:Ehcache RESTFul Web Services API暴露了單例的CacheManager,他能在ehcache.xml或者IoC容器里面配置。
    標(biāo)準(zhǔn)服務(wù)端包含了內(nèi)嵌的Glassfish web容器。它被打成了war包,可以任意部署到支持Servlet 2.5的web容器內(nèi)。Glassfish V2/3、Tomcat 6和Jetty 6都已經(jīng)經(jīng)過(guò)了測(cè)試。

    10、搜索
    標(biāo)準(zhǔn)分布式搜索使用了流式查詢接口的方式,請(qǐng)參閱文檔。

    11、Java EE和應(yīng)用緩存
    為普通緩存場(chǎng)景和模式提供高質(zhì)量的實(shí)現(xiàn)。
    阻塞緩存:它的機(jī)制避免了復(fù)制進(jìn)程并發(fā)操作的問(wèn)題。
    SelfPopulatingCache在緩存一些開(kāi)銷昂貴操作時(shí)顯得特別有用,它是一種針對(duì)讀優(yōu)化的緩存。它不需要調(diào)用者知道緩存元素怎樣被返回,也支持在不阻塞讀的情況下刷新緩存條目。
    CachingFilter:一個(gè)抽象、可擴(kuò)展的cache filter。
    SimplePageCachingFilter:用于緩存基于request URI和Query String的頁(yè)面。它可以根據(jù)HTTP request header的值來(lái)選擇采用或者不采用gzip壓縮方式將頁(yè)面發(fā)到瀏覽器端。你可以用它來(lái)緩存整個(gè)Servlet頁(yè)面,無(wú)論你采用的是JSP、 velocity,或者其他的頁(yè)面渲染技術(shù)。
    SimplePageFragmentCachingFilter:緩存頁(yè)面片段,基于request URI和Query String。在JSP中使用jsp:include標(biāo)簽包含。
    已經(jīng)使用Orion和Tomcat測(cè)試過(guò),兼容Servlet 2.3、Servlet 2.4規(guī)范。
    Cacheable命令:這是一種老的命令行模式,支持異步行為、容錯(cuò)。
    兼容Hibernate,兼容Google App Engine。
    基于JTA的事務(wù)支持,支持事務(wù)資源管理,二階段提交和回滾,以及本地事務(wù)。

    12、開(kāi)源協(xié)議
    Apache 2.0 license

     

    二、Ehcache的加載模塊列表 ,他們都是獨(dú)立的庫(kù),每個(gè)都為Ehcache添加新的功能,可以在此下載 

     

    • ehcache-core:API,標(biāo)準(zhǔn)緩存引擎,RMI復(fù)制和Hibernate支持
    • ehcache:分布式Ehcache,包括Ehcache的核心和Terracotta的庫(kù)
    • ehcache-monitor:企業(yè)級(jí)監(jiān)控和管理
    • ehcache-web:為Java Servlet Container提供緩存、gzip壓縮支持的filters
    • ehcache-jcache:JSR107 JCACHE的實(shí)現(xiàn)
    • ehcache-jgroupsreplication:使用JGroup的復(fù)制
    • ehcache-jmsreplication:使用JMS的復(fù)制
    • ehcache-openjpa:OpenJPA插件
    • ehcache-server:war內(nèi)部署或者單獨(dú)部署的RESTful cache server
    • ehcache-unlockedreadsview:允許Terracotta cache的無(wú)鎖讀
    • ehcache-debugger:記錄RMI分布式調(diào)用事件
    • Ehcache for Ruby:Jruby and Rails支持

    Ehcache的結(jié)構(gòu)設(shè)計(jì)概覽:

    三、核心定義

     

    cache manager:緩存管理器,以前是只允許單例的,不過(guò)現(xiàn)在也可以多實(shí)例了

    cache:緩存管理器內(nèi)可以放置若干cache,存放數(shù)據(jù)的實(shí)質(zhì),所有cache都實(shí)現(xiàn)了Ehcache接口

    element:?jiǎn)螚l緩存數(shù)據(jù)的組成單位

    system of record(SOR):可以取到真實(shí)數(shù)據(jù)的組件,可以是真正的業(yè)務(wù)邏輯、外部接口調(diào)用、存放真實(shí)數(shù)據(jù)的數(shù)據(jù)庫(kù)等等,緩存就是從SOR中讀取或者寫入到SOR中去的。

     

    代碼示例:

    Java代碼  收藏代碼
    1. CacheManager manager = CacheManager.newInstance( "src/config/ehcache.xml" );  
    2. manager.addCache("testCache");  
    3. Cache test = singletonManager.getCache("testCache");  
    4. test.put(new Element("key1""value1"));  
    5. manager.shutdown();  

    當(dāng)然,也支持這種類似DSL的配置方式,配置都是可以在運(yùn)行時(shí)動(dòng)態(tài)修改的:

    Java代碼  收藏代碼
    1. Cache testCache =  new  Cache(  
    2.   new CacheConfiguration("testCache", maxElements)  
    3.     .memoryStoreEvictionPolicy(MemoryStoreEvictionPolicy.LFU)  
    4.     .overflowToDisk(true)  
    5.     .eternal(false)  
    6.     .timeToLiveSeconds(60)  
    7.     .timeToIdleSeconds(30)  
    8.     .diskPersistent(false)  
    9.     .diskExpiryThreadIntervalSeconds(0));  

    事務(wù)的例子:

    Java代碼  收藏代碼
    1. Ehcache cache = cacheManager.getEhcache( "xaCache" );  
    2. transactionManager.begin();  
    3. try  {  
    4.     Element e = cache.get(key);  
    5.     Object result = complexService.doStuff(element.getValue());  
    6.     cache.put(new Element(key, result));  
    7.     complexService.doMoreStuff(result);  
    8.     transactionManager.commit();  
    9. catch (Exception e) {  
    10.     transactionManager.rollback();  
    11. }  

     

    四、一致性模型

     

    說(shuō)到一致性,數(shù)據(jù)庫(kù)的一致性是怎樣的?不妨先來(lái)回顧一下數(shù)據(jù)庫(kù)的幾個(gè)隔離級(jí)別:

    未提交讀(Read Uncommitted):在讀數(shù)據(jù)時(shí)不會(huì)檢查或使用任何鎖。因此,在這種隔離級(jí)別中可能讀取到?jīng)]有提交的數(shù)據(jù)。會(huì)出現(xiàn)臟讀、不可重復(fù)讀、幻象讀。
    已提交讀(Read Committed):只讀取提交的數(shù)據(jù)并等待其他事務(wù)釋放排他鎖。讀數(shù)據(jù)的共享鎖在讀操作完成后立即釋放。已提交讀是數(shù)據(jù)庫(kù)的默認(rèn)隔離級(jí)別。會(huì)出現(xiàn)不可重復(fù)讀、幻象讀。
    可重復(fù)讀(Repeatable Read):像已提交讀級(jí)別那樣讀數(shù)據(jù),但會(huì)保持共享鎖直到事務(wù)結(jié)束。會(huì)出現(xiàn)幻象讀。
    可序列化(Serializable):工作方式類似于可重復(fù)讀。但它不僅會(huì)鎖定受影響的數(shù)據(jù),還會(huì)鎖定這個(gè)范圍,這就阻止了新數(shù)據(jù)插入查詢所涉及的范圍。

     

    基于以上,再來(lái)對(duì)比思考下面的一致性模型:

     

    1、強(qiáng)一致性模型:系統(tǒng)中的某個(gè)數(shù)據(jù)被成功更新(事務(wù)成功返回)后,后續(xù)任何對(duì)該數(shù)據(jù)的讀取操作都得到更新后的值。這是傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)提供的一致性模型,也是關(guān)系數(shù)據(jù)庫(kù)深受人們喜愛(ài)的原因之一。強(qiáng)一致性模型下的性能消耗通常是最大的。

     

    2、弱一致性模型:系統(tǒng)中的某個(gè)數(shù)據(jù)被更新后,后續(xù)對(duì)該數(shù)據(jù)的讀取操作得到的不一定是更新后的值,這種情況下通常有個(gè)“不一致性時(shí)間窗口”存在:即數(shù)據(jù)更新完成后在經(jīng)過(guò)這個(gè)時(shí)間窗口,后續(xù)讀取操作就能夠得到更新后的值。

     

    3、最終一致性模型:屬于弱一致性的一種,即某個(gè)數(shù)據(jù)被更新后,如果該數(shù)據(jù)后續(xù)沒(méi)有被再次更新,那么最終所有的讀取操作都會(huì)返回更新后的值。

     

    最終一致性模型包含如下幾個(gè)必要屬性,都比較好理解:

     

    • 讀寫一致:某線程A,更新某條數(shù)據(jù)以后,后續(xù)的訪問(wèn)全部都能取得更新后的數(shù)據(jù)。
    • 會(huì)話內(nèi)一致:它本質(zhì)上和上面那一條是一致的,某用戶更改了數(shù)據(jù),只要會(huì)話還存在,后續(xù)他取得的所有數(shù)據(jù)都必須是更改后的數(shù)據(jù)。
    • 單調(diào)讀一致:如果一個(gè)進(jìn)程可以看到當(dāng)前的值,那么后續(xù)的訪問(wèn)不能返回之前的值。
    • 單調(diào)寫一致:對(duì)同一進(jìn)程內(nèi)的寫行為必須是保序的,否則,寫完畢的結(jié)果就是不可預(yù)期的了。

    4、Bulk Load:這種模型是基于批量加載數(shù)據(jù)到緩存里面的場(chǎng)景而優(yōu)化的,沒(méi)有引入鎖和常規(guī)的淘汰算法這些降低性能的東西,它和最終一致性模型很像,但是有批量、高速寫和弱一致性保證的機(jī)制。

     

    這樣幾個(gè)API也會(huì)影響到一致性的結(jié)果:

     

    1、顯式鎖(Explicit Locking :如果我們本身就配置為強(qiáng)一致性,那么自然所有的緩存操作都具備事務(wù)性質(zhì)。而如果我們配置成最終一致性時(shí),再在外部使用顯式鎖API,也可以達(dá)到事務(wù)的效果。當(dāng)然這樣的鎖可以控制得更細(xì)粒度,但是依然可能存在競(jìng)爭(zhēng)和線程阻塞。

     

    2、無(wú)鎖可讀取視圖(UnlockedReadsView):一個(gè)允許臟讀的decorator,它只能用在強(qiáng)一致性的配置下,它通過(guò)申請(qǐng)一個(gè)特殊的寫鎖來(lái)比完全的強(qiáng)一致性配置提升性能。

    舉例如下,xml配置為強(qiáng)一致性模型:

    Xml代碼  收藏代碼
    1. < cache   name = "myCache"   
    2.      maxElementsInMemory="500"  
    3.      eternal="false"  
    4.      overflowToDisk="false"  
    5.    <terracotta clustered="true" consistency="strong" />  
    6. </ cache >   

    但是使用UnlockedReadsView:

    Java代碼  收藏代碼
    1. Cache cache = cacheManager.getEhcache( "myCache" );  
    2. UnlockedReadsView unlockedReadsView = new UnlockedReadsView(cache, "myUnlockedCache");  

     

    3、原子方法(Atomic methods):方法執(zhí)行是原子化的,即CAS操作(Compare and Swap)。CAS最終也實(shí)現(xiàn)了強(qiáng)一致性的效果,但不同的是,它是采用樂(lè)觀鎖而不是悲觀鎖來(lái)實(shí)現(xiàn)的。在樂(lè)觀鎖機(jī)制下,更新的操作可能不成功,因?yàn)樵谶@過(guò)程中可能會(huì)有其他線程對(duì)同一條數(shù)據(jù)進(jìn)行變更,那么在失敗后需要重新執(zhí)行更新操作。現(xiàn)代的CPU都支持CAS原語(yǔ)了。

    Java代碼  收藏代碼
    1. cache.putIfAbsent(Element element);  
    2. cache.replace(Element oldOne, Element newOne);  
    3. cache.remove(Element);  

     

    五、緩存拓?fù)漕愋?/strong>

     

    1、獨(dú)立緩存(Standalone Ehcache):這樣的緩存應(yīng)用節(jié)點(diǎn)都是獨(dú)立的,互相不通信。

     

    2、分布式緩存(Distributed Ehcache):數(shù)據(jù)存儲(chǔ)在Terracotta的服務(wù)器陣列(Terracotta Server Array,TSA)中,但是最近使用的數(shù)據(jù),可以存儲(chǔ)在各個(gè)應(yīng)用節(jié)點(diǎn)中。

     

    邏輯視角:


    L1緩存就在各個(gè)應(yīng)用節(jié)點(diǎn)上,而L2緩存則放在Cache Server陣列中。

     

    組網(wǎng)視角:

     

    模型存儲(chǔ)視角:


    L1級(jí)緩存是沒(méi)有持久化存儲(chǔ)的。另外,從緩存數(shù)據(jù)量上看,server端遠(yuǎn)大于應(yīng)用節(jié)點(diǎn)。

     

    3、復(fù)制式緩存(Replicated Ehcache):緩存數(shù)據(jù)時(shí)同時(shí)存放在多個(gè)應(yīng)用節(jié)點(diǎn)的,數(shù)據(jù)復(fù)制和失效的事件以同步或者異步的形式在各個(gè)集群節(jié)點(diǎn)間傳播。上述事件到來(lái)時(shí),會(huì)阻塞寫線程的操作。在這種模式下,只有弱一致性模型。

     

    它有如下幾種事件傳播機(jī)制:RMI、JGroups、JMS和Cache Server。

     

    RMI模式下,所有節(jié)點(diǎn)全部對(duì)等:

     

    JGroup模式:可以配置單播或者多播,協(xié)議棧和配置都非常靈活。

     

    Xml代碼  收藏代碼
    1. < cacheManagerPeerProviderFactory   
    2. class = "net.sf.ehcache.distribution.jgroups.JGroupsCacheManagerPeerProviderFactory"   
    3. properties =" connect = UDP ( mcast_addr = 231 .12.21.132; mcast_port = 45566 ;):PING:  
    4. MERGE2:FD_SOCK:VERIFY_SUSPECT:pbcast.NAKACK:UNICAST:pbcast.STABLE:FRAG:pbcast.GMS"  
    5. propertySeparator = "::"   
    6. />   

     

     

    JMS模式:這種模式的核心就是一個(gè)消息隊(duì)列,每個(gè)應(yīng)用節(jié)點(diǎn)都訂閱預(yù)先定義好的主題,同時(shí),節(jié)點(diǎn)有元素更新時(shí),也會(huì)發(fā)布更新元素到主題中去。JMS規(guī)范實(shí)現(xiàn)者上,Open MQ和Active MQ這兩個(gè),Ehcache的兼容性都已經(jīng)測(cè)試過(guò)。

    Cache Server模式:這種模式下存在主從節(jié)點(diǎn),通信可以通過(guò)RESTful的API或者SOAP。

    無(wú)論上面哪個(gè)模式,更新事件又可以分為updateViaCopy或updateViaInvalidate,后者只是發(fā)送一個(gè)過(guò)期消息,效率要高得多。

    復(fù)制式緩存容易出現(xiàn)數(shù)據(jù)不一致的問(wèn)題,如果這成為一個(gè)問(wèn)題,可以考慮使用數(shù)據(jù)同步分發(fā)的機(jī)制。

     

    即便不采用分布式緩存和復(fù)制式緩存,依然會(huì)出現(xiàn)一些不好的行為,比如:

     

    緩存漂移(Cache Drift):每個(gè)應(yīng)用節(jié)點(diǎn)只管理自己的緩存,在更新某個(gè)節(jié)點(diǎn)的時(shí)候,不會(huì)影響到其他的節(jié)點(diǎn),這樣數(shù)據(jù)之間可能就不同步了。這在web會(huì)話數(shù)據(jù)緩存中情況尤甚。

     

    數(shù)據(jù)庫(kù)瓶頸(Database Bottlenecks ):對(duì)于單實(shí)例的應(yīng)用來(lái)說(shuō),緩存可以保護(hù)數(shù)據(jù)庫(kù)的讀風(fēng)暴;但是,在集群的環(huán)境下,每一個(gè)應(yīng)用節(jié)點(diǎn)都要定期保持?jǐn)?shù)據(jù)最新,節(jié)點(diǎn)越多,要維持這樣的情況對(duì)數(shù)據(jù)庫(kù)的開(kāi)銷也越大。

     

    六、存儲(chǔ)方式

     

    1、堆內(nèi)存儲(chǔ):速度快,但是容量有限。

     

    2、堆外(OffHeapStore)存儲(chǔ):被稱為BigMemory,只在企業(yè)版本的Ehcache中提供,原理是利用nio的DirectByteBuffers實(shí)現(xiàn),比存儲(chǔ)到磁盤上快,而且完全不受GC的影響,可以保證響應(yīng)時(shí)間的穩(wěn)定性;但是direct buffer的在分配上的開(kāi)銷要比heap buffer大,而且要求必須以字節(jié)數(shù)組方式存儲(chǔ),因此對(duì)象必須在存儲(chǔ)過(guò)程中進(jìn)行序列化,讀取則進(jìn)行反序列化操作,它的速度大約比堆內(nèi)存儲(chǔ)慢一個(gè)數(shù)量級(jí)。

    (注:direct buffer不受GC影響,但是direct buffer歸屬的的JAVA對(duì)象是在堆上且能夠被GC回收的,一旦它被回收,JVM將釋放direct buffer的堆外空間。)

     

    3、磁盤存儲(chǔ)

     

    七、緩存使用模式

     

    cache-aside:直接操作。先詢問(wèn)cache某條緩存數(shù)據(jù)是否存在,存在的話直接從cache中返回?cái)?shù)據(jù),繞過(guò)SOR;如果不存在,從SOR中取得數(shù)據(jù),然后再放入cache中。

     

    Java代碼  收藏代碼
    1. public  V readSomeData(K key)   
    2. {  
    3.    Element element;  
    4.    if ((element = cache.get(key)) != null) {  
    5.        return element.getValue();  
    6.    }  
    7.    if (value = readDataFromDataStore(key)) != null) {  
    8.        cache.put(new Element(key, value));  
    9.    }   
    10.    return value;  
    11. }  

     

    cache-as-sor:結(jié)合了read-through、write-through或write-behind操作,通過(guò)給SOR增加了一層代理,對(duì)外部應(yīng)用訪問(wèn)來(lái)說(shuō),它不用區(qū)別數(shù)據(jù)是從緩存中還是從SOR中取得的。

    read-through

    write-through

    write-behind(write-back):既將寫的過(guò)程變?yōu)楫惒降模诌M(jìn)一步延遲寫入數(shù)據(jù)的過(guò)程。

     

     

    Copy Cache的兩個(gè)模式:CopyOnRead和CopyOnWrite。

    CopyOnRead指的是在讀緩存數(shù)據(jù)的請(qǐng)求到達(dá)時(shí),如果發(fā)現(xiàn)數(shù)據(jù)已經(jīng)過(guò)期,需要重新從源處獲取,發(fā)起的copy element的操作(pull);

    CopyOnWrite則是發(fā)生在真實(shí)數(shù)據(jù)寫入緩存時(shí),發(fā)起的更新其他節(jié)點(diǎn)的copy element的操作(push)。

     

    前者適合在不允許多個(gè)線程訪問(wèn)同一個(gè)element的時(shí)候使用,后者則允許你自由控制緩存更新通知的時(shí)機(jī)。

    更多push和pull的變化和不同,也可參見(jiàn)這里

     

    八、多種配置方式

     

    包括配置文件、聲明式配置、編程式配置,甚至通過(guò)指定構(gòu)造器的參數(shù)來(lái)完成配置,配置設(shè)計(jì)的原則包括:

    所有配置要放到一起

    緩存的配置可以很容易在開(kāi)發(fā)階段、運(yùn)行時(shí)修改

    錯(cuò)誤的配置能夠在程序啟動(dòng)時(shí)發(fā)現(xiàn),在運(yùn)行時(shí)修改出錯(cuò)則需要拋出運(yùn)行時(shí)異常

    提供默認(rèn)配置,幾乎所有的配置都是可選的,都有默認(rèn)值

     

    九、自動(dòng)資源控制 (Automatic Resource Control,ARC):

     

    它是提供了一種智能途徑來(lái)控制緩存,調(diào)優(yōu)性能。特性包括:

    內(nèi)存內(nèi)緩存對(duì)象大小的控制,避免OOM出現(xiàn)

    池化(cache manager級(jí)別)的緩存大小獲取,避免單獨(dú)計(jì)算緩存大小的消耗

    靈活的獨(dú)立基于層的大小計(jì)算能力,下圖中可以看到,不同層的大小都是可以單獨(dú)控制的

    可以統(tǒng)計(jì)字節(jié)大小、緩存條目數(shù)和百分比

    優(yōu)化高命中數(shù)據(jù)的獲取,以提升性能,參見(jiàn)下面對(duì)緩存數(shù)據(jù)在不同層之間的流轉(zhuǎn)的介紹

    緩存數(shù)據(jù)的流轉(zhuǎn)包括了這樣幾種行為:

    Flush:緩存條目向低層次移動(dòng)。

    Fault:從低層拷貝一個(gè)對(duì)象到高層。在獲取緩存的過(guò)程中,某一層發(fā)現(xiàn)自己的該緩存條目已經(jīng)失效,就觸發(fā)了Fault行為。

    Eviction:把緩存條目除去。

    Expiration:失效狀態(tài)。

    Pinning:強(qiáng)制緩存條目保持在某一層。

    下面的圖反映了數(shù)據(jù)在各個(gè)層之間的流轉(zhuǎn),也反映了數(shù)據(jù)的生命周期:

     

    十、監(jiān)控功能

     

    監(jiān)控的拓?fù)洌?/p>


    每個(gè)應(yīng)用節(jié)點(diǎn)部署一個(gè)監(jiān)控探針,通過(guò)TCP協(xié)議與監(jiān)控服務(wù)器聯(lián)系,最終將數(shù)據(jù)提供給富文本客戶端或者監(jiān)控操作服務(wù)器。

     

    十一、廣域網(wǎng)復(fù)制

    緩存數(shù)據(jù)復(fù)制方面,Ehcache允許兩個(gè)地理位置各異的節(jié)點(diǎn)在廣域網(wǎng)下維持?jǐn)?shù)據(jù)一致性,同時(shí)它提供了這樣幾種方案(注:下面的示例都只繪制了兩個(gè)節(jié)點(diǎn)的情形,實(shí)際可以推廣到N個(gè)節(jié)點(diǎn)):

     

    第一種方案:Terracotta Active/Mirror Replication


    這種方案下,服務(wù)端包含一個(gè)活躍節(jié)點(diǎn),一個(gè)備份節(jié)點(diǎn);各個(gè)應(yīng)用節(jié)點(diǎn)全部靠該活躍節(jié)點(diǎn)提供讀寫服務(wù)。這種方式最簡(jiǎn)單,管理容易;但是,需要寄希望于理想的網(wǎng)絡(luò)狀況,服務(wù)器之間和客戶端到服務(wù)器之間都存在走WAN的情況,這樣的方案其實(shí)最不穩(wěn)定。

     

    第二種方案:Transactional Cache Manager Replication


    這種方案下,數(shù)據(jù)讀取不需要經(jīng)過(guò)WAN,寫入數(shù)據(jù)時(shí)寫入兩份,分別由兩個(gè)cache manager處理,一份在本地Server,一份到其他Server去。這種方案下讀的吞吐量較高而且延遲較低;但是需要引入一個(gè)XA事務(wù)管理器,兩個(gè) cache manager寫兩份數(shù)據(jù)導(dǎo)致寫開(kāi)銷較大,而且過(guò)WAN的寫延遲依然可能導(dǎo)致系統(tǒng)響應(yīng)的瓶頸。

     

    第三種方案:Messaging based (AMQ) replication


    這種方案下,引入了批量處理和隊(duì)列,用以減緩WAN的瓶頸出現(xiàn),同時(shí),把處理讀請(qǐng)求和復(fù)制邏輯從Server Array物理上就剝離開(kāi),避免了WAN情況惡化對(duì)節(jié)點(diǎn)讀取業(yè)務(wù)的影響。這種方案要較高的吞吐量和較低的延遲,讀/復(fù)制的分離保證了可以提供完備的消息分發(fā)保證、沖突處理等特性;但是它較為復(fù)雜,而且還需要一個(gè)消息總線。

     

    有一些Ehcache特性應(yīng)用較少或者比較邊緣化,沒(méi)有提到,例如對(duì)于JMX的支持;還有一些則是有類似的特性和介紹了,例如對(duì)于WEB的支持,請(qǐng)參見(jiàn)我這篇關(guān)于OSCache的解讀,其中的“web支持”一節(jié)有詳細(xì)的原理分析。

     

    最后,關(guān)于Ehcache的性能比對(duì),下面這張圖來(lái)自Ehcache的創(chuàng)始人Greg Luck的blog

     

    put/get 上Ehcache要500-1000倍快過(guò)Memcached。原因何在?他自己分析道:“In-process caching and asynchronous replication are a clear performance winner”。有關(guān)它詳細(xì)的內(nèi)容還是請(qǐng)參閱他的blog吧。

    posted on 2013-12-31 13:56 午后星期午 閱讀(119) 評(píng)論(0)  編輯  收藏 所屬分類: JavaEE

    主站蜘蛛池模板: a级毛片高清免费视频| 久久国产乱子伦精品免费一| 久久免费视频网站| 国产免费av片在线看| 国产亚洲美日韩AV中文字幕无码成人 | 亚洲中文字幕无码日韩| 亚洲日本视频在线观看| 成年免费大片黄在线观看com| 久草免费手机视频| 国产极品粉嫩泬免费观看 | 亚洲AV无码国产丝袜在线观看| 亚洲AV成人噜噜无码网站| 亚洲精品视频免费| 啦啦啦高清视频在线观看免费| 国产亚洲自拍一区| 亚洲一卡2卡3卡4卡乱码 在线 | 亚洲成人高清在线| 亚洲va在线va天堂成人| 国产自国产自愉自愉免费24区| 女人被男人桶得好爽免费视频| 亚洲成AV人片在WWW色猫咪| 鲁死你资源站亚洲av| 18禁止看的免费污网站| 国产亚洲一区区二区在线| 亚洲欧美aⅴ在线资源| 久久综合给合久久国产免费| 亚洲成A人片77777国产| 亚洲 欧洲 日韩 综合在线| 国产成人久久AV免费| 亚洲成网777777国产精品| 在线观看亚洲AV每日更新无码| 蜜桃视频在线观看免费视频网站WWW| 免费人成无码大片在线观看| 狠狠色香婷婷久久亚洲精品| 一级毛片不卡片免费观看| 久久亚洲中文字幕精品一区| 亚洲av日韩av永久在线观看| AV无码免费永久在线观看| 亚洲免费在线播放| a在线免费观看视频| 亚洲一区无码精品色|