www.久久久久|狼友网站av天堂|精品国产无码a片|一级av色欲av|91在线播放视频|亚洲无码主播在线|国产精品草久在线|明星AV网站在线|污污内射久久一区|婷婷综合视频网站

當(dāng)前位置:首頁 > 公眾號精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]最近在看Mybatis的源碼,剛好看到緩存這一塊,Mybatis提供了一級緩存和二級緩存;一級緩存相對來說比較簡單,功能比較齊全的是二級緩存,基本上滿足了一個緩存該有的功能;當(dāng)然如果拿來和專門的緩存框架如ehcache來對比可能稍有差距;本文我們將來整理一下實現(xiàn)一個本地緩存都應(yīng)該需要考慮哪些東西。

來源:ksfzhaohui |?http://dwz.win/Ws4

最近在看Mybatis的源碼,剛好看到緩存這一塊,Mybatis提供了一級緩存和二級緩存;一級緩存相對來說比較簡單,功能比較齊全的是二級緩存,基本上滿足了一個緩存該有的功能;當(dāng)然如果拿來和專門的緩存框架如ehcache來對比可能稍有差距;本文我們將來整理一下實現(xiàn)一個本地緩存都應(yīng)該需要考慮哪些東西。

考慮點

考慮點主要在數(shù)據(jù)用何種方式存儲,能存儲多少數(shù)據(jù),多余的數(shù)據(jù)如何處理等幾個點,下面我們來詳細(xì)的介紹每個考慮點,以及該如何去實現(xiàn);

1.數(shù)據(jù)結(jié)構(gòu)

首要考慮的就是數(shù)據(jù)該如何存儲,用什么數(shù)據(jù)結(jié)構(gòu)存儲,最簡單的就直接用Map來存儲數(shù)據(jù);或者復(fù)雜的如redis一樣提供了多種數(shù)據(jù)類型哈希,列表,集合,有序集合等,底層使用了雙端鏈表,壓縮列表,集合,跳躍表等數(shù)據(jù)結(jié)構(gòu);

2.對象上限

因為是本地緩存,內(nèi)存有上限,所以一般都會指定緩存對象的數(shù)量比如1024,當(dāng)達(dá)到某個上限后需要有某種策略去刪除多余的數(shù)據(jù);

3.清除策略

上面說到當(dāng)達(dá)到對象上限之后需要有清除策略,常見的比如有LRU(最近最少使用)、FIFO(先進(jìn)先出)、LFU(最近最不常用)、SOFT(軟引用)、WEAK(弱引用)等策略;

4.過期時間

除了使用清除策略,一般本地緩存也會有一個過期時間設(shè)置,比如redis可以給每個key設(shè)置一個過期時間,這樣當(dāng)達(dá)到過期時間之后直接刪除,采用清除策略+過期時間雙重保證;

5.線程安全

像redis是直接使用單線程處理,所以就不存在線程安全問題;而我們現(xiàn)在提供的本地緩存往往是可以多個線程同時訪問的,所以線程安全是不容忽視的問題;并且線程安全問題是不應(yīng)該拋給使用者去保證;

6.簡明的接口

提供一個傻瓜式的對外接口是很有必要的,對使用者來說使用此緩存不是一種負(fù)擔(dān)而是一種享受;提供常用的get,put,remove,clear,getSize方法即可;

7.是否持久化

這個其實不是必須的,是否需要將緩存數(shù)據(jù)持久化看需求;本地緩存如ehcache是支持持久化的,而guava是沒有持久化功能的;分布式緩存如redis是有持久化功能的,memcached是沒有持久化功能的;

8.阻塞機制

在看Mybatis源碼的時候,二級緩存提供了一個blocking標(biāo)識,表示當(dāng)在緩存中找不到元素時,它設(shè)置對緩存鍵的鎖定;這樣其他線程將等待此元素被填充,而不是命中數(shù)據(jù)庫;其實我們使用緩存的目的就是因為被緩存的數(shù)據(jù)生成比較費時,比如調(diào)用對外的接口,查詢數(shù)據(jù)庫,計算量很大的結(jié)果等等;這時候如果多個線程同時調(diào)用get方法獲取的結(jié)果都為null,每個線程都去執(zhí)行一遍費時的計算,其實也是對資源的浪費;最好的辦法是只有一個線程去執(zhí)行,其他線程等待,計算一次就夠了;但是此功能基本上都交給使用者來處理,很少有本地緩存有這種功能;

如何實現(xiàn)

以上大致介紹了實現(xiàn)一個本地緩存我們都有哪些需要考慮的地方,當(dāng)然可能還有其他沒有考慮到的點;下面繼續(xù)看看關(guān)于每個點都應(yīng)該如何去實現(xiàn),重點介紹一下思路;

1.數(shù)據(jù)結(jié)構(gòu)

本地緩存最常見的是直接使用Map來存儲,比如guava使用ConcurrentHashMap,ehcache也是用了ConcurrentHashMap,Mybatis二級緩存使用HashMap來存儲:

????Map<Object,?Object>?cache?=?new?ConcurrentHashMap<Object,?Object>()Mybatis使用HashMap本身是非線程安全的,所以可以看到起內(nèi)部使用了一個SynchronizedCache用來包裝,保證線程的安全性; ?

當(dāng)然除了使用Map來存儲,可能還使用其他數(shù)據(jù)結(jié)構(gòu)來存儲,比如redis使用了雙端鏈表,壓縮列表,整數(shù)集合,跳躍表和字典;當(dāng)然這主要是因為redis對外提供的接口很豐富除了哈希還有列表,集合,有序集合等功能;

2.對象上限

本地緩存常見的一個屬性,一般緩存都會有一個默認(rèn)值比如1024,在用戶沒有指定的情況下默認(rèn)指定;當(dāng)緩存的數(shù)據(jù)達(dá)到指定最大值時,需要有相關(guān)策略從緩存中清除多余的數(shù)據(jù)這就涉及到下面要介紹的清除策略;

3.清除策略

配合對象上限之后使用,場景的清除策略如:LRU(最近最少使用)、FIFO(先進(jìn)先出)、LFU(最近最不常用)、SOFT(軟引用)、WEAK(弱引用);?
LRU :Least Recently
Used的縮寫最近最少使用,移除最長時間不被使用的對象;常見的使用LinkedHashMap來實現(xiàn),也是很多本地緩存默認(rèn)使用的策略;?
FIFO :先進(jìn)先出,按對象進(jìn)入緩存的順序來移除它們;常見使用隊列Queue來實現(xiàn);?
LFU :Least Frequently
Used的縮寫大概也是最近最少使用的意思,和LRU有點像;區(qū)別點在LRU的淘汰規(guī)則是基于訪問時間,而LFU是基于訪問次數(shù)的;可以通過HashMap并且記錄訪問次數(shù)來實現(xiàn);?
SOFT :軟引用基于垃圾回收器狀態(tài)和軟引用規(guī)則移除對象;常見使用SoftReference來實現(xiàn);?
WEAK :弱引用更積極地基于垃圾收集器狀態(tài)和弱引用規(guī)則移除對象;常見使用WeakReference來實現(xiàn);

4.過期時間

設(shè)置過期時間,讓緩存數(shù)據(jù)在指定時間過后自動刪除;常見的過期數(shù)據(jù)刪除策略有兩種方式:被動刪除和主動刪除;?
被動刪除 :每次進(jìn)行g(shù)et/put操作的時候都會檢查一下當(dāng)前key是否已經(jīng)過期,如果過期則刪除,類似如下代碼:

????if?(System.currentTimeMillis()?-?lastClear?>?clearInterval)?{
??????????clear();
????}
????

主動刪除 :專門有一個job在后臺定期去檢查數(shù)據(jù)是否過期,如果過期則刪除,這其實可以有效的處理冷數(shù)據(jù);

5.線程安全

盡量用線程安全的類去存儲數(shù)據(jù),比如使用ConcurrentHashMap代替HashMap;或者提供相應(yīng)的同步處理類,比如Mybatis提供了SynchronizedCache:

?????public?synchronized?void?putObject(Object?key,?Object?object)?{
????????...省略...
??????}

??????@Override
??????public?synchronized?Object?getObject(Object?key)?{
????????...省略...
??????}
????

6.簡明的接口

提供常用的get,put,remove,clear,getSize方法即可,比如Mybatis的Cache接口:

????public?interface?Cache?{
??????String?getId();
??????void?putObject(Object?key,?Object?value);
??????Object?getObject(Object?key);
??????Object?removeObject(Object?key);
??????void?clear();
??????int?getSize();
??????ReadWriteLock?getReadWriteLock();
????}
????

再來看看guava提供的Cache接口,相對來說也是比較簡潔的:

????public?interface?Cache<K,?V>?{
??????V?getIfPresent(@CompatibleWith("K")?Object?key);
??????V?get(K?key,?Callable?loader)?throws?ExecutionException;
??????ImmutableMap?getAllPresent(Iterable?keys);
??????void?put(K?key,?V?value);
??????void?putAll(Map?m);
??????void?invalidate(@CompatibleWith("K")?Object?key);
??????void?invalidateAll(Iterable?keys);
??????void?invalidateAll();
??????long?size();
??????CacheStats?stats();
??????ConcurrentMap?asMap();
??????void?cleanUp();
????}

7.是否持久化

持久化的好處是重啟之后可以再次加載文件中的數(shù)據(jù),這樣就起到類似熱加載的功效;比如ehcache提供了是否持久化磁盤緩存的功能,將緩存數(shù)據(jù)存放在一個.data文件中;

????diskPersistent="false"?//是否持久化磁盤緩存

redis更是將持久化功能發(fā)揮到極致,慢慢的有點像數(shù)據(jù)庫了;提供了AOF和RDB兩種持久化方式;當(dāng)然很多情況下可以配合使用兩種方式;

8.阻塞機制

除了在Mybatis中看到了BlockingCache來實現(xiàn)此功能,之前在看< > 的時候其中有實現(xiàn)一個很完美的緩存,大致代碼如下:

????public?class?Memoizerl<A,?V>?implements?Computable<A,?V>?{
????????private?final?Map>?cache?=?new?ConcurrentHashMap>();
????????private?final?Computable?c;

????????public?Memoizerl(Computable?c)?{
????????????this.c?=?c;
????????}

????????@Override
????????public?V?compute(A?arg)?throws?InterruptedException,?ExecutionException?{
????????????while?(true)?{
????????????????Future?f?=?cache.get(arg);
????????????????if?(f?==?null)?{
????????????????????Callable?eval?=?new?Callable()?{
????????????????????????@Override
????????????????????????public?V?call()?throws?Exception?{
????????????????????????????return?c.compute(arg);
????????????????????????}
????????????????????};
????????????????????FutureTask?ft?=?new?FutureTask(eval);
????????????????????f?=?cache.putIfAbsent(arg,?ft);
????????????????????if?(f?==?null)?{
????????????????????????f?=?ft;
????????????????????????ft.run();
????????????????????}
????????????????????try?{
????????????????????????return?f.get();
????????????????????}?catch?(CancellationException?e)?{
????????????????????????cache.remove(arg,?f);
????????????????????}
????????????????}
????????????}
????????}
????}

compute是一個計算很費時的方法,所以這里把計算的結(jié)果緩存起來,但是有個問題就是如果兩個線程同時進(jìn)入此方法中怎么保證只計算一次,這里最核心的地方在于使用了ConcurrentHashMap的putIfAbsent方法,同時只會寫入一個FutureTask;

總結(jié)

本文大致介紹了要設(shè)計一個本地緩存都需要考慮哪些點:數(shù)據(jù)結(jié)構(gòu),對象上限,清除策略,過期時間,線程安全,阻塞機制,實用的接口,是否持久化;當(dāng)然肯定有其他考慮點,歡迎補充。

特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:

如何設(shè)計一個強悍的本地緩存?

如何設(shè)計一個強悍的本地緩存?

如何設(shè)計一個強悍的本地緩存?

長按訂閱更多精彩▼

如何設(shè)計一個強悍的本地緩存?

如有收獲,點個在看,誠摯感謝

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉