阿里P8技術(shù)專家細(xì)究分布式緩存問題

今天給大家整理一篇關(guān)于Redis經(jīng)常被問到的問題:緩存雪崩、緩存穿透弃锐、緩存預(yù)熱粪躬、緩存更新官硝、緩存降級等概念

一、緩存雪崩

緩存雪崩我們可以簡單的理解為:由于原有緩存失效短蜕,新緩存未到期間(例如:我們設(shè)置緩存時采用了相同的過期時間氢架,在同一時刻出現(xiàn)大面積的緩存過期),所有原本應(yīng)該訪問緩存的請求都去查詢數(shù)據(jù)庫了朋魔,而對數(shù)據(jù)庫CPU和內(nèi)存造成巨大壓力岖研,嚴(yán)重的會造成數(shù)據(jù)庫宕機(jī)。從而形成一系列連鎖反應(yīng),造成整個系統(tǒng)崩潰孙援。

緩存正常從Redis中獲取害淤,示意圖如下:

緩存失效瞬間示意圖如下:

緩存失效時的雪崩效應(yīng)對底層系統(tǒng)的沖擊非常可怕拓售!大多數(shù)系統(tǒng)設(shè)計(jì)者考慮用加鎖或者隊(duì)列的方式保證來保證不會有大量的線程對數(shù)據(jù)庫一次性進(jìn)行讀寫窥摄,從而避免失效時大量的并發(fā)請求落到底層存儲系統(tǒng)上。還有一個簡單方案就時講緩存失效時間分散開础淤,比如我們可以在原有的失效時間基礎(chǔ)上增加一個隨機(jī)值崭放,比如1-5分鐘隨機(jī),這樣每一個緩存的過期時間的重復(fù)率就會降低鸽凶,就很難引發(fā)集體失效的事件币砂。

以下簡單介紹兩種實(shí)現(xiàn)方式的偽代碼:

(1)碰到這種情況,一般并發(fā)量不是特別多的時候玻侥,使用最多的解決方案是加鎖排隊(duì)决摧,偽代碼如下:

加鎖排隊(duì)只是為了減輕數(shù)據(jù)庫的壓力,并沒有提高系統(tǒng)吞吐量凑兰。假設(shè)在高并發(fā)下掌桩,緩存重建期間key是鎖著的,這是過來1000個請求999個都在阻塞的姑食。同樣會導(dǎo)致用戶等待超時波岛,這是個治標(biāo)不治本的方法!

注意:加鎖排隊(duì)的解決方式分布式環(huán)境的并發(fā)問題矢门,有可能還要解決分布式鎖的問題盆色;線程還會被阻塞,用戶體驗(yàn)很差祟剔!因此隔躲,在真正的高并發(fā)場景下很少使用!

(2)還有一個解決辦法解決方案是:給每一個緩存數(shù)據(jù)增加相應(yīng)的緩存標(biāo)記物延,記錄緩存的是否失效宣旱,如果緩存標(biāo)記失效,則更新數(shù)據(jù)緩存叛薯,實(shí)例偽代碼如下:

解釋說明:

1浑吟、緩存標(biāo)記:記錄緩存數(shù)據(jù)是否過期,如果過期會觸發(fā)通知另外的線程在后臺去更新實(shí)際key的緩存耗溜;

2组力、緩存數(shù)據(jù):它的過期時間比緩存標(biāo)記的時間延長1倍,例:標(biāo)記緩存時間30分鐘抖拴,數(shù)據(jù)緩存設(shè)置為60分鐘燎字。 這樣腥椒,當(dāng)緩存標(biāo)記key過期后,實(shí)際緩存還能把舊數(shù)據(jù)返回給調(diào)用端候衍,直到另外的線程在后臺更新完成后笼蛛,才會返回新緩存。

關(guān)于緩存崩潰的解決方法蛉鹿,這里提出了三種方案:使用鎖或隊(duì)列滨砍、設(shè)置過期標(biāo)志更新緩存、為key設(shè)置不同的緩存失效時間妖异,還有一各被稱為“二級緩存”的解決方法惋戏,有興趣的讀者可以自行研究。

二随闺、緩存穿透

緩存穿透是指用戶查詢數(shù)據(jù)日川,在數(shù)據(jù)庫沒有蔓腐,自然在緩存中也不會有矩乐。這樣就導(dǎo)致用戶查詢的時候,在緩存中找不到回论,每次都要去數(shù)據(jù)庫再查詢一遍散罕,然后返回空(相當(dāng)于進(jìn)行了兩次無用的查詢)。這樣請求就繞過緩存直接查數(shù)據(jù)庫傀蓉,這也是經(jīng)常提的緩存命中率問題欧漱。

有很多種方法可以有效地解決緩存穿透問題,最常見的則是采用布隆過濾器葬燎,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的bitmap中误甚,一個一定不存在的數(shù)據(jù)會被這個bitmap攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力谱净。

另外也有一個更為簡單粗暴的方法窑邦,如果一個查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在,還是系統(tǒng)故障)壕探,我們?nèi)匀话堰@個空結(jié)果進(jìn)行緩存冈钦,但它的過期時間會很短,最長不超過五分鐘李请。通過這個直接設(shè)置的默認(rèn)值存放到緩存瞧筛,這樣第二次到緩沖中獲取就有值了,而不會繼續(xù)訪問數(shù)據(jù)庫导盅,這種辦法最簡單粗暴较幌!

把空結(jié)果,也給緩存起來白翻,這樣下次同樣的請求就可以直接返回空了乍炉,即可以避免當(dāng)查詢的值為空時引起的緩存穿透。同時也可以單獨(dú)設(shè)置個緩存區(qū)域存儲空值,對要查詢的key進(jìn)行預(yù)先校驗(yàn)恩急,然后再放行給后面的正常緩存處理邏輯杉畜。

三、緩存預(yù)熱

緩存預(yù)熱這個應(yīng)該是一個比較常見的概念衷恭,相信很多小伙伴都應(yīng)該可以很容易的理解此叠,緩存預(yù)熱就是系統(tǒng)上線后,將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng)随珠。這樣就可以避免在用戶請求的時候灭袁,先查詢數(shù)據(jù)庫,然后再將數(shù)據(jù)緩存的問題窗看!用戶直接查詢事先被預(yù)熱的緩存數(shù)據(jù)茸歧!

針對上面的技術(shù)我特意整理了一下,如果想學(xué)習(xí)Java工程化显沈、高性能及分布式软瞎、深入淺出。微服務(wù)拉讯、Spring涤浇,MyBatis,Netty源碼分析的朋友可以加Java進(jìn)階群:582505643魔慷,群里有阿里大牛直播講解技術(shù)只锭,以及Java大型互聯(lián)網(wǎng)開源技術(shù)的視頻免費(fèi)分享給大家。

解決思路:

1院尔、直接寫個緩存刷新頁面蜻展,上線時手工操作下;

2邀摆、數(shù)據(jù)量不大纵顾,可以在項(xiàng)目啟動的時候自動進(jìn)行加載;

3隧熙、定時刷新緩存片挂;

四、緩存更新

除了緩存服務(wù)器自帶的緩存失效策略之外(Redis默認(rèn)的有6中策略可供選擇)贞盯,我們還可以根據(jù)具體的業(yè)務(wù)需求進(jìn)行自定義的緩存淘汰音念,常見的策略有兩種:

(1)定時去清理過期的緩存;

(2)當(dāng)有用戶請求過來時躏敢,再判斷這個請求所用到的緩存是否過期闷愤,過期的話就去底層系統(tǒng)得到新數(shù)據(jù)并更新緩存。

兩者各有優(yōu)劣件余,第一種的缺點(diǎn)是維護(hù)大量緩存的key是比較麻煩的讥脐,第二種的缺點(diǎn)就是每次用戶請求過來都要判斷緩存失效遭居,邏輯相對比較復(fù)雜!具體用哪種方案旬渠,大家可以根據(jù)自己的應(yīng)用場景來權(quán)衡俱萍。

五、緩存降級

當(dāng)訪問量劇增告丢、服務(wù)出現(xiàn)問題(如響應(yīng)時間慢或不響應(yīng))或非核心服務(wù)影響到核心流程的性能時枪蘑,仍然需要保證服務(wù)還是可用的,即使是有損服務(wù)岖免。系統(tǒng)可以根據(jù)一些關(guān)鍵數(shù)據(jù)進(jìn)行自動降級岳颇,也可以配置開關(guān)實(shí)現(xiàn)人工降級。

降級的最終目的是保證核心服務(wù)可用颅湘,即使是有損的话侧。而且有些服務(wù)是無法降級的(如加入購物車、結(jié)算)闯参。

在進(jìn)行降級之前要對系統(tǒng)進(jìn)行梳理瞻鹏,看看系統(tǒng)是不是可以丟卒保帥;從而梳理出哪些必須誓死保護(hù)赢赊,哪些可降級乙漓;比如可以參考日志級別設(shè)置預(yù)案:

(1)一般:比如有些服務(wù)偶爾因?yàn)榫W(wǎng)絡(luò)抖動或者服務(wù)正在上線而超時级历,可以自動降級释移;

(2)警告:有些服務(wù)在一段時間內(nèi)成功率有波動(如在95~100%之間),可以自動降級或人工降級寥殖,并發(fā)送告警玩讳;

(3)錯誤:比如可用率低于90%,或者數(shù)據(jù)庫連接池被打爆了嚼贡,或者訪問量突然猛增到系統(tǒng)能承受的最大閥值熏纯,此時可以根據(jù)情況自動降級或者人工降級;

(4)嚴(yán)重錯誤:比如因?yàn)樘厥庠驍?shù)據(jù)錯誤了粤策,此時需要緊急人工降級樟澜。

(5)針對上面的技術(shù)我特意整理了一下,如果想學(xué)習(xí)Java工程化叮盘、高性能及分布式秩贰、深入淺出。微服務(wù)柔吼、Spring毒费,MyBatis,Netty源碼分析的朋友可以加Java進(jìn)階群:582505643愈魏,群里有阿里大牛直播講解技術(shù)觅玻,以及Java大型互聯(lián)網(wǎng)開源技術(shù)的視頻免費(fèi)分享給大家想际。

六、總結(jié)

這些都是實(shí)際項(xiàng)目中溪厘,可能碰到的一些問題胡本,也是面試的時候經(jīng)常會被問到的知識點(diǎn),實(shí)際上還有很多很多各種各樣的問題畸悬,文中的解決方案打瘪,也不可能滿足所有的場景,相對來說只是對該問題的入門解決方法傻昙。一般正式的業(yè)務(wù)場景往往要復(fù)雜的多闺骚,應(yīng)用場景不同,方法和解決方案也不同妆档,由于上述方案僻爽,考慮的問題并不是很全面,因此并不適用于正式的項(xiàng)目開發(fā)贾惦,但是可以作為概念理解入門胸梆,具體解決方案可以去看看一個視頻網(wǎng)站的解說


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市须板,隨后出現(xiàn)的幾起案子碰镜,更是在濱河造成了極大的恐慌,老刑警劉巖习瑰,帶你破解...
    沈念sama閱讀 210,914評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件绪颖,死亡現(xiàn)場離奇詭異,居然都是意外死亡甜奄,警方通過查閱死者的電腦和手機(jī)柠横,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來课兄,“玉大人牍氛,你說我怎么就攤上這事⊙滩” “怎么了搬俊?”我有些...
    開封第一講書人閱讀 156,531評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蜒茄。 經(jīng)常有香客問我唉擂,道長,這世上最難降的妖魔是什么扩淀? 我笑而不...
    開封第一講書人閱讀 56,309評論 1 282
  • 正文 為了忘掉前任楔敌,我火速辦了婚禮,結(jié)果婚禮上驻谆,老公的妹妹穿的比我還像新娘卵凑。我一直安慰自己庆聘,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評論 5 384
  • 文/花漫 我一把揭開白布勺卢。 她就那樣靜靜地躺著伙判,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黑忱。 梳的紋絲不亂的頭發(fā)上宴抚,一...
    開封第一講書人閱讀 49,730評論 1 289
  • 那天,我揣著相機(jī)與錄音甫煞,去河邊找鬼菇曲。 笑死,一個胖子當(dāng)著我的面吹牛抚吠,可吹牛的內(nèi)容都是我干的常潮。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼楷力,長吁一口氣:“原來是場噩夢啊……” “哼喊式!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起萧朝,我...
    開封第一講書人閱讀 37,643評論 0 266
  • 序言:老撾萬榮一對情侶失蹤岔留,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后检柬,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體献联,經(jīng)...
    沈念sama閱讀 44,095評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評論 2 325
  • 正文 我和宋清朗相戀三年厕吉,在試婚紗的時候發(fā)現(xiàn)自己被綠了酱固。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,566評論 1 339
  • 序言:一個原本活蹦亂跳的男人離奇死亡头朱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出龄减,到底是詐尸還是另有隱情项钮,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評論 4 328
  • 正文 年R本政府宣布希停,位于F島的核電站烁巫,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏宠能。R本人自食惡果不足惜亚隙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望违崇。 院中可真熱鬧阿弃,春花似錦诊霹、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至入愧,卻和暖如春鄙漏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背棺蛛。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評論 1 264
  • 我被黑心中介騙來泰國打工怔蚌, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人旁赊。 一個月前我還...
    沈念sama閱讀 46,248評論 2 360
  • 正文 我出身青樓媚创,卻偏偏與公主長得像,于是被迫代替她去往敵國和親彤恶。 傳聞我的和親對象是個殘疾皇子钞钙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評論 2 348

推薦閱讀更多精彩內(nèi)容