日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

Java Cache 的HashMap實(shí)現(xiàn), 適用場(chǎng)景及分布式ehcache實(shí)例

 WindySky 2016-05-24

 

cache是老生常談的事情,這里我想強(qiáng)調(diào)一下KISS原則,就是keep it simple and stupid。最近看到很多場(chǎng)景下cache使用的不適當(dāng),特別是被過(guò)度使用了。一個(gè)簡(jiǎn)單鍵值存儲(chǔ)并不需要復(fù)雜的cache方案,好的方案就是用最簡(jiǎn)單的方法解決問(wèn)題。簡(jiǎn)潔是美!

 

一個(gè)標(biāo)準(zhǔn)Cache的主要特征是:

過(guò)期時(shí)間       

容量規(guī)劃(重要)

清除策略(重要)

命中率統(tǒng)計(jì) 

 

基于以上特征,使用HashMap作為本地cache似乎很不適當(dāng)。更重要的是,有不少朋友認(rèn)為HashMap可能會(huì)使內(nèi)存耗盡。其實(shí)不然,自jdk1.2后,Java就引入了WeakHashMap??纯碼pi文檔是怎么說(shuō)的:對(duì)于一個(gè)給定的鍵,其映射的存在并不阻止垃圾回收器對(duì)該鍵的丟棄,這就使該鍵成為可終止的,被終止,然后被回收。丟棄某個(gè)鍵時(shí),其條目從映射中有效地移除,因此,該類的行為與其他的 Map 實(shí)現(xiàn)有所不同。

 

這個(gè)翻譯明顯有點(diǎn)爛,總結(jié)一下,和強(qiáng)引用的HashMap相比,WeakHashMap在本身引用不被回收的前提下允許GC回收它的鍵值對(duì)。當(dāng)GC發(fā)現(xiàn)內(nèi)存即將耗盡且沒(méi)有其他對(duì)象可以釋放時(shí),會(huì)主動(dòng)回收WeakHashMap所占用的對(duì)象。因此使用WeakHashMap作為本地cache是不會(huì)造成內(nèi)存耗盡。如果你僅僅需要一個(gè)簡(jiǎn)單的鍵值對(duì)存儲(chǔ),而并不關(guān)心命中率統(tǒng)計(jì),那么放心的使用WeakHashMap作為cache吧。

 

通過(guò)簡(jiǎn)單的包裝,就可以為你的HashMap增加過(guò)期時(shí)間和容量規(guī)劃。而且比其他cache更高效。openfire的DefaultCache就是一個(gè)很好的例子:http://svn./svn/repos/openfire/trunk/src/java/org/jivesoftware/util/cache/DefaultCache.java

 

DefaultCache的核心是HashMap,另外增加了一層很薄的包裝來(lái)實(shí)現(xiàn)過(guò)期和LRU。DefaultCache包括兩個(gè)LinkedList,一個(gè)用于存儲(chǔ)插入順序,另一個(gè)用于存儲(chǔ)插入時(shí)間。當(dāng)添加cache時(shí),都addFirst。當(dāng)cache size達(dá)到臨界值時(shí),從最尾部刪除。有朋友測(cè)試過(guò),比ehcache快5倍。

 

如果本地cache不能滿足你的要求,ehcache是個(gè)很好的選擇。不僅僅作為分布式的cache,甚至作為狀態(tài)同步,ehcache都有非常優(yōu)秀的案例。也可以實(shí)現(xiàn)多機(jī)copy。分享一個(gè)數(shù)據(jù),某生產(chǎn)系統(tǒng)中ehcache每天處理17,466,415次replication。

 

基于ehcache的分布式緩存,你可以簡(jiǎn)單的實(shí)現(xiàn)分布式計(jì)算。分析一個(gè)場(chǎng)景,某iOS后端服務(wù)要求用戶先注冊(cè)ios設(shè)備,可以按下圖處理設(shè)備信息。DeviceServer接受device注冊(cè)后同步copy的本地cache和ehcache。該ehcache按以下方式配置成對(duì)。本地cache再定期(每隔幾秒鐘)從ehcache中加載peer server注冊(cè)的數(shù)據(jù)。

 

 

ehcache.xml 寫道
<cacheManagerPeerProviderFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerProviderFactory"
properties="peerDiscovery=manual,
rmiUrls=//192.168.0.1:20121/testCache"/>

<cacheManagerPeerListenerFactory
class="net.sf.ehcache.distribution.RMICacheManagerPeerListenerFactory"
properties="hostName=192.168.0.2,port=20121,socketTimeoutMillis=60000"/>

<cache name="testCache"
maxElementsInMemory="20000"
eternal="false"
overflowToDisk="false"
memoryStoreEvictionPolicy="LRU">
<cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
properties="replicateAsynchronously=true,
replicatePuts=true,
replicateUpdates=true,
replicateUpdatesViaCopy=true,
asynchronousReplicationIntervalMillis=2000"
/>
</cache>
 

peer server的hostName和rmiUrls配置需要做相應(yīng)改動(dòng)。

 

偽代碼如下

 

 

Java style fake code代碼  收藏代碼
  1. init() {  
  2.     cacheManager = new net.sf.ehcache.CacheManager(ThisClass.class.getResource("/ehcache.xml"));  
  3.     testCache = cacheManager.getCache("testCache");  
  4. }  
  5.   
  6. sync() {  
  7.     while(true) {  
  8.         List keys = testCache.getKeysNoDuplicateCheck();  
  9.   
  10.         for (int i = 0; i < keys.size(); i++) {  
  11.             net.sf.ehcache.Element element = testCache.get(keys.get(i));  
  12.             MyObj changed = (MyObj) element.getValue();  
  13.             // do magic  
  14.   
  15.             testCache.remove(keys.get(i), true);  
  16.         }  
  17.     }  
  18. }  
 

 

根據(jù)KISS原則,建議簡(jiǎn)單狀態(tài)同步都使用ehcache完成。知識(shí)投入低,且易于維護(hù)。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多