Spring Boot入門(第三十四章):緩存

1、為什么要用緩存

現(xiàn)在我們系統(tǒng)里面的數(shù)據(jù)還比較少蜓耻,所以頁面看起來還是比較快蜡镶,但是隨著數(shù)據(jù)量的增長雾袱,我們很快就會發(fā)現(xiàn)頁面會越來越慢,這時我們就需要進(jìn)行優(yōu)化官还。之前我們很多接口服務(wù)做了多次查詢谜酒,一個服務(wù)執(zhí)行多次sql,當(dāng)然會慢妻枕,大部分情況下盡量我們最好執(zhí)行一次sql僻族,但是執(zhí)行一次sql,就會增加代碼的復(fù)雜度屡谐,本來邏輯很清楚的代碼述么,變成了一個復(fù)雜的sql語句,這時我們可以考慮使用緩存愕掏。再者sql的優(yōu)化也是有限的度秘,也許已經(jīng)優(yōu)化得最優(yōu)了,sql執(zhí)行還是比較長饵撑,這時我們用緩存可以緩存數(shù)據(jù)庫的壓力剑梳,以前需要幾秒才能返回的服務(wù),現(xiàn)在只需要毫秒級的時間滑潘。

2垢乙、緩存的缺點(diǎn)

雖然緩存可以大大提高服務(wù)的效率,但是他也有不少缺點(diǎn)语卤。

首先追逮,緩存一般第一次訪問的時候還是會比較慢酪刀,因?yàn)樗枰跏蓟鞘孪阮A(yù)知用戶會訪問哪些數(shù)據(jù)钮孵,事先緩存骂倘。

其次,緩存有時效性巴席,緩存的數(shù)據(jù)不可能一直有效历涝,一直有效的數(shù)據(jù)那是常量了,緩存的數(shù)據(jù)一般有兩種情況漾唉,一種是設(shè)置有效時間荧库,超過時間自動清除,另一種是需要開發(fā)人員編程手動去清除毡证,當(dāng)然可以兩者結(jié)合。如果我們緩存的數(shù)據(jù)更新非常頻繁蔫仙,那么緩存就沒太大意義料睛,除非業(yè)務(wù)可以接受數(shù)據(jù)的延遲。假如我們平均每秒鐘會發(fā)布一篇文章摇邦,我們將文章列表緩存起來恤煞,有效時間設(shè)為1秒鐘,這樣施籍,sql每秒鐘最多執(zhí)行1次居扒,發(fā)布的文章基本上可以實(shí)時看到,但是如果sql執(zhí)行效率比較低丑慎,1秒鐘執(zhí)行一次還是困難喜喂,我們可以將緩存設(shè)置為1分鐘,這樣1分鐘最多執(zhí)行一次竿裂,但是用戶得接受新發(fā)布的文章可能需要1分鐘以后才能看到玉吁。

最后,緩存增加了編程的復(fù)雜性腻异,我們不僅需要考慮如何設(shè)置緩存进副,還需要考慮如何清除緩存,往往我們看到的很多異常數(shù)據(jù)悔常,經(jīng)常都是因?yàn)榫彺鏇]有正確更新導(dǎo)致的影斑。

3、緩存的類型

我們有很多東西都可以用來作為緩存的容器机打,最簡單的矫户,我們直接使用容器的內(nèi)存就可以作為緩存,但這種情況只適合單機(jī)部署残邀。分布式應(yīng)用時吏垮,我們經(jīng)常使用Redis作為緩存介質(zhì)障涯。其余的還有很多如Guava,Caffeine等等膳汪。

4唯蝶、Spring Cache

Spring提供了緩存的通用接口,我們可以使用注解的方式遗嗽,或者編程的方式操作緩存粘我。但是由于各個緩存介質(zhì)支持的功能有所不同,所以Spring只能抽象出通用的接口痹换。例如Redis是支持設(shè)置緩存有效時間的征字,而我們的內(nèi)存緩存不支持,所以Spring緩存的通用接口不能進(jìn)行有效時間設(shè)置娇豫。如果需要用到這一特性匙姜,我們可以直接使用Spring Redis的接口進(jìn)行編程。

4.1注解緩存

spring提供了幾個注解用來操作緩存冯痢。首先我們需要使用@EnableCaching打開注解緩存

我們以CmsController為例氮昧,對getCategoryTree方法進(jìn)行緩存,因?yàn)槲覀兊姆诸悩浜苌侔l(fā)生改變

這里我們使用了@Cacheable注解浦楣。我們在方法內(nèi)部打個斷點(diǎn)袖肥,我們訪問頁面,第一次進(jìn)入斷點(diǎn)振劳,刷新界面椎组,發(fā)現(xiàn)不會再進(jìn)入斷點(diǎn),說明我們的緩存生效了历恐。

重啟應(yīng)用后寸癌,再次訪問頁面,第一次會再次進(jìn)入斷點(diǎn)弱贼,因?yàn)镾pring默認(rèn)使用的內(nèi)存介質(zhì)是Simple灵份,即容器內(nèi)存,容器內(nèi)存會隨著應(yīng)用的停止而釋放哮洽,所以緩存也會跟著釋放填渠。要想持久化可以選擇其他緩存,例如Redis鸟辅。

4.2編程緩存

上面使用注解加了緩存氛什,要想緩存的數(shù)據(jù)一直保持正確,我們必須在分類數(shù)據(jù)修改的時候清除緩存匪凉,清除緩存對應(yīng)注解@CacheEvict枪眉,但是我們修改分類的方法都是在基類完成的,不方便用注解控制再层,我們可以直接用編程的方式來控制贸铜。

我們首先去掉之前的@Cacheable注解堡纬,然后注入一個CacheManager

CacheManager就是Spring抽象出來的統(tǒng)一處理緩存的管理工具類。

從上面可以看到蒿秦,以前只需一個注解就可以完成的功能烤镐,現(xiàn)在我們需要更多的代碼去處理。

同樣棍鳖,現(xiàn)在我們需要在分類變更時處理緩存炮叶,

這里,我們選擇在分類數(shù)據(jù)新增渡处,修改和刪除的時候镜悉,直接清除緩存,這樣医瘫,下次訪問的時候侣肄,就會重新查詢數(shù)據(jù)庫。

5醇份、定時清除

不管是上面的注解緩存稼锅,還是編程緩存,因?yàn)槲覀儸F(xiàn)在緩存的時效性都是永久被芳,為了保證緩存的正確性缰贝,我們都必須確保在數(shù)據(jù)修改時進(jìn)行緩存更新馍悟。我們必須確保所有可能導(dǎo)致數(shù)據(jù)變化的接口服務(wù)都能監(jiān)聽處理到畔濒。隨著項(xiàng)目越來越大,可能涉及數(shù)據(jù)修改的接口也越來越多锣咒,很容易漏掉侵状。所以有時候選擇定時清除緩存可能更加簡單可靠。

上面說了毅整,緩存的時效性并不是所有緩存介質(zhì)都支持趣兄,我們的內(nèi)存緩存就不支持,但是我們還是可以通過自己編程來實(shí)現(xiàn)悼嫉。例如艇潭,上面的例子,我們完全就可以建立一個定時任務(wù)來定時清理緩存戏蔑。這里我們簡單實(shí)現(xiàn)一個定時清除的功能蹋凝。

我們在CmsController添加一個構(gòu)造方法,在構(gòu)造方法里面啟動一個線程总棵,該線程每過1分鐘鳍寂,將會自動清除緩存,這樣基本上可以保證我們最遲1分鐘以后看到最新數(shù)據(jù)情龄。

對于很多系統(tǒng)迄汛,首頁有很多統(tǒng)計(jì)報(bào)表捍壤,報(bào)表一般業(yè)務(wù)復(fù)雜,查詢慢鞍爱,如果報(bào)表的實(shí)時性要求不是那么高鹃觉,我們就可以采用這種方法。但是這種方法在緩存清除后硬霍,第一次查詢還是會有點(diǎn)慢帜慢,我們可以進(jìn)一步優(yōu)化,在緩存過期前唯卖,先查詢數(shù)據(jù)粱玲。

這樣,除了容器啟動第一次查詢慢拜轨,后面每次都會以最快的速度返回抽减。這種方式可以理解為饑餓式,之前的為懶漢式橄碾。

6卵沉、Redis緩存

在分布式部署的時候,我們一般必須使用Redis緩存法牲,使用Redis緩存也狠簡單史汗,我們只需要修改配置即可

7、總結(jié)

這節(jié)主要講解緩存的作用和使用方式拒垃,說到底緩存就是一個Map停撞,篇幅有限,很多地方?jīng)]有細(xì)講悼瓮,需要大家在實(shí)戰(zhàn)中理解戈毒。

代碼:

https://github.com/www15119258/springboot-study/tree/branch34

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市横堡,隨后出現(xiàn)的幾起案子埋市,更是在濱河造成了極大的恐慌,老刑警劉巖命贴,帶你破解...
    沈念sama閱讀 216,692評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件道宅,死亡現(xiàn)場離奇詭異,居然都是意外死亡胸蛛,警方通過查閱死者的電腦和手機(jī)污茵,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,482評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來胚泌,“玉大人省咨,你說我怎么就攤上這事$枋遥” “怎么了零蓉?”我有些...
    開封第一講書人閱讀 162,995評論 0 353
  • 文/不壞的土叔 我叫張陵笤受,是天一觀的道長。 經(jīng)常有香客問我敌蜂,道長箩兽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,223評論 1 292
  • 正文 為了忘掉前任章喉,我火速辦了婚禮汗贫,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘秸脱。我一直安慰自己落包,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,245評論 6 388
  • 文/花漫 我一把揭開白布摊唇。 她就那樣靜靜地躺著咐蝇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪巷查。 梳的紋絲不亂的頭發(fā)上有序,一...
    開封第一講書人閱讀 51,208評論 1 299
  • 那天,我揣著相機(jī)與錄音岛请,去河邊找鬼旭寿。 笑死,一個胖子當(dāng)著我的面吹牛崇败,可吹牛的內(nèi)容都是我干的盅称。 我是一名探鬼主播,決...
    沈念sama閱讀 40,091評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼僚匆,長吁一口氣:“原來是場噩夢啊……” “哼微渠!你這毒婦竟也來了搭幻?” 一聲冷哼從身側(cè)響起咧擂,我...
    開封第一講書人閱讀 38,929評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎檀蹋,沒想到半個月后松申,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,346評論 1 311
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡俯逾,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,570評論 2 333
  • 正文 我和宋清朗相戀三年贸桶,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片桌肴。...
    茶點(diǎn)故事閱讀 39,739評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡皇筛,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出坠七,到底是詐尸還是另有隱情水醋,我是刑警寧澤旗笔,帶...
    沈念sama閱讀 35,437評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站拄踪,受9級特大地震影響蝇恶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜惶桐,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,037評論 3 326
  • 文/蒙蒙 一撮弧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧姚糊,春花似錦贿衍、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,677評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至忿薇,卻和暖如春裙椭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背署浩。 一陣腳步聲響...
    開封第一講書人閱讀 32,833評論 1 269
  • 我被黑心中介騙來泰國打工揉燃, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人筋栋。 一個月前我還...
    沈念sama閱讀 47,760評論 2 369
  • 正文 我出身青樓炊汤,卻偏偏與公主長得像,于是被迫代替她去往敵國和親弊攘。 傳聞我的和親對象是個殘疾皇子抢腐,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,647評論 2 354