Guava Cache是一款非常優(yōu)秀的本地緩存框架。
這篇文章,我們聊聊如何使用 Guava Cache 異步刷新技巧帶飛系統(tǒng)性能 。
圖片
Guava Cache 的數(shù)據(jù)結(jié)構(gòu)跟 JDK1.7 的 ConcurrentHashMap 類似,提供了基于時(shí)間、容量、引用三種回收策略,以及自動(dòng)加載、訪問(wèn)統(tǒng)計(jì)等功能。
圖片
首先,我們溫習(xí)下 Gauva Cache 的經(jīng)典配置 。
圖片
例子中,緩存最大容量設(shè)置為 100 (基于容量進(jìn)行回收),配置了失效策略和刷新策略。
配置 expireAfterWrite 后,緩存項(xiàng)在被創(chuàng)建或最后一次更新后的指定時(shí)間內(nèi)會(huì)過(guò)期。
配置 refreshAfterWrite 設(shè)置刷新時(shí)間,當(dāng)緩存項(xiàng)過(guò)期的同時(shí)可以重新加載新值 。
這個(gè)例子里,有的同學(xué)可能會(huì)有疑問(wèn):為什么需要配置刷新策略,只配置失效策略不就可以嗎?
當(dāng)然是可以的,但在高并發(fā)場(chǎng)景下,配置刷新策略會(huì)有奇效,接下來(lái),我們會(huì)寫一個(gè)測(cè)試用例,方便大家理解 Gauva Cache 的線程模型。
我們模擬在多線程場(chǎng)景下,「緩存過(guò)期執(zhí)行 load 方法」和「刷新執(zhí)行 reload 方法」兩者的運(yùn)行情況。
圖片
執(zhí)行結(jié)果見下圖:
圖片
執(zhí)行結(jié)果表明:Guava Cache 并沒有后臺(tái)任務(wù)線程異步的執(zhí)行 load 或者 reload 方法。
失效策略:expireAfterWrite 允許一個(gè)線程執(zhí)行 load 方法,其他線程阻塞等待 。當(dāng)大量線程用相同的 key 獲取緩存值時(shí),只會(huì)有一個(gè)線程進(jìn)入 load 方法,而其他線程則等待,直到緩存值被生成。這樣也就避免了緩存擊穿的危險(xiǎn)。高并發(fā)場(chǎng)景下 ,這樣還是會(huì)阻塞大量線程。
刷新策略:refreshAfterWrite 允許一個(gè)線程執(zhí)行 load 方法,其他線程返回舊的值。單個(gè) key 并發(fā)下,使用 refreshAfterWrite ,雖然不會(huì)阻塞了,但是如果恰巧同時(shí)多個(gè) key 同時(shí)過(guò)期,還是會(huì)給數(shù)據(jù)庫(kù)造成壓力。
為了提升系統(tǒng)性能,我們可以從如下兩個(gè)方面來(lái)優(yōu)化 :
下圖展示優(yōu)化方案的時(shí)間軸 :
圖片
圖片
圖片
不管使用哪種方案, 都需要定義單獨(dú)的線程池來(lái)執(zhí)行刷新任務(wù) 。
2018 年,筆者服務(wù)的一家電商公司需要進(jìn)行 app 首頁(yè)接口的性能優(yōu)化。筆者花了大概兩天的時(shí)間完成了整個(gè)方案,采取的是兩級(jí)緩存模式,同時(shí)采用了 Guava 的異步刷新機(jī)制。
整體架構(gòu)如下圖所示:
圖片
緩存讀取流程如下 :
優(yōu)化后,性能表現(xiàn)很好,平均耗時(shí)在 5ms 左右,同時(shí)大幅度的減少應(yīng)用 GC 的頻率。
該方案依然有瑕疵,一天晚上我們發(fā)現(xiàn) app 端首頁(yè)顯示的數(shù)據(jù)時(shí)而相同,時(shí)而不同。
也就是說(shuō):雖然 LoadingCache 線程一直在調(diào)用接口更新緩存信息,但是各個(gè)服務(wù)器本地緩存中的數(shù)據(jù)并非完成一致。
這說(shuō)明了兩個(gè)很重要的點(diǎn):
最終,我們的解決方案是:
Guava Cache 非常強(qiáng)大,它并沒有后臺(tái)任務(wù)線程異步的執(zhí)行 load 或者 reload 方法,而是通過(guò)請(qǐng)求線程來(lái)執(zhí)行相關(guān)操作。
為了提升系統(tǒng)性能,我們可以從如下兩個(gè)方面來(lái)處理 :
筆者曾經(jīng)優(yōu)化過(guò)某電商網(wǎng)站的首頁(yè)接口,使用的方案是:Guava 的異步刷新機(jī)制 + 多級(jí)緩存 ,取得了非常好的優(yōu)化效果。
盡管如此,我們?cè)谑褂眠@種方式時(shí),依然需要考慮的緩存和數(shù)據(jù)庫(kù)一致性問(wèn)題。
參考資料:
https://albenw.github.io/posts/df42dc84/
本文鏈接:http://www.www897cc.com/showinfo-26-57379-0.htmlGuava Cache 異步刷新技巧,你值得擁有!
聲明:本網(wǎng)頁(yè)內(nèi)容旨在傳播知識(shí),若有侵權(quán)等問(wèn)題請(qǐng)及時(shí)與本網(wǎng)聯(lián)系,我們將在第一時(shí)間刪除處理。郵件:2376512515@qq.com