緩存三大問題解決方案


title: 緩存三大問題解決方案
date: 2021/05/25 10:57


緩存穿透

緩存穿透指的是查詢一個(gè)一定不存在的數(shù)據(jù)期揪,由于存儲(chǔ)層在查不到數(shù)據(jù)時(shí)不寫入緩存掉奄,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層查詢,從而失去了緩存的意義凤薛。

如果有人利用不存在的key頻繁攻擊我們的應(yīng)用姓建,可能 DB 就掛掉了诞仓。

解決方案

  1. 布隆過濾器,將所有可能存在的數(shù)據(jù) hash 到一個(gè)足夠大的 bitmap 中速兔,一個(gè)一定不存在的數(shù)據(jù)則會(huì)被攔截掉墅拭,從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢壓力。

因?yàn)?BloomFilter 如果聲稱其中包含元素憨栽,則可能是錯(cuò)誤的帜矾,但是如果聲明其中不包含元素,則肯定是正確的屑柔。

  1. 空值緩存:如果一個(gè)查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在屡萤,還是系統(tǒng)故障),我們?nèi)匀话堰@個(gè)空結(jié)果進(jìn)行緩存掸宛,但它的過期時(shí)間會(huì)很短死陆,最長不超過五分鐘,這樣則可以應(yīng)對(duì)短時(shí)間的大量的該key攻擊唧瘾,設(shè)置為較短的失效時(shí)間是因?yàn)樵撝悼赡軜I(yè)務(wù)無關(guān)措译,存在意義不大,且該次的查詢也未必是攻擊者發(fā)起饰序,無過久存儲(chǔ)的必要领虹,故可以早點(diǎn)失效。

緩存雪崩

緩存雪崩是指在我們設(shè)置緩存時(shí)采用了相同的過期時(shí)間求豫,導(dǎo)致緩存在某一時(shí)刻同時(shí)失效塌衰,請(qǐng)求全部轉(zhuǎn)發(fā)到DB,DB瞬時(shí)壓力過重雪崩蝠嘉。

另一種情況是緩存服務(wù)器宕機(jī)最疆,也會(huì)造成雪崩現(xiàn)象。

解決方案

  1. 永不過期:簡單粗暴

  2. 線程互斥:通過分布式鎖只允許一個(gè)線程構(gòu)建緩存蚤告,其他線程等待構(gòu)建緩存的線程執(zhí)行完努酸,重新從緩存獲取數(shù)據(jù)才可以,每個(gè)時(shí)刻只有一個(gè)線程在執(zhí)行請(qǐng)求杜恰,減輕了db的壓力获诈,但缺點(diǎn)也很明顯,降低了系統(tǒng)的qps箫章。

  3. 交錯(cuò)失效時(shí)間:這種方法時(shí)間比較簡單粗暴烙荷,既然在同一時(shí)間失效會(huì)造成請(qǐng)求過多雪崩,那我們錯(cuò)開不同的失效時(shí)間即可從一定長度上避免這種問題檬寂,在緩存進(jìn)行失效時(shí)間設(shè)置的時(shí)候终抽,從某個(gè)適當(dāng)?shù)闹涤蛑须S機(jī)一個(gè)時(shí)間作為失效時(shí)間即可。

  4. 請(qǐng)求限流:

    • 限制請(qǐng)求數(shù)量,常見的限流算法有滑動(dòng)窗口昼伴,令牌桶算法和漏桶算法匾旭,或者直接使用隊(duì)列、加鎖(信號(hào)量)等
    • 限制數(shù)據(jù)庫的每秒請(qǐng)求數(shù)圃郊,避免數(shù)據(jù)庫掛掉价涝。對(duì)于被限流的請(qǐng)求,采用服務(wù)降級(jí)處理持舆,比如提供默認(rèn)的值色瘩,或者空白值
  5. 本地緩存:如果使用本地緩存,即使分布式緩存掛了逸寓,也可以將數(shù)據(jù)庫查詢的結(jié)果緩存到本地居兆,避免后續(xù)請(qǐng)求全部達(dá)到數(shù)據(jù)庫中

  6. 緩存高可用:使用Redis Sentinel等搭建緩存的高可用竹伸,避免緩存掛掉無法提供服務(wù)的情況泥栖,從而降低出現(xiàn)緩存雪崩的情況

緩存擊穿

緩存擊穿實(shí)際上是緩存雪崩的一個(gè)特例,對(duì)于一些設(shè)置了過期時(shí)間的key勋篓,如果這些key可能會(huì)在某些時(shí)間點(diǎn)被超高并發(fā)地訪問吧享,由于系統(tǒng)中對(duì)這些熱點(diǎn)的數(shù)據(jù)緩存也存在失效時(shí)間,在熱點(diǎn)的緩存到達(dá)失效時(shí)間時(shí)譬嚣,此時(shí)可能依然會(huì)有大量的請(qǐng)求到達(dá)系統(tǒng)钢颂,沒有了緩存層的保護(hù),這些請(qǐng)求同樣的會(huì)到達(dá)db從而可能引起故障拜银。擊穿與雪崩的區(qū)別即在于擊穿是對(duì)于特定的熱點(diǎn)數(shù)據(jù)來說甸陌,而雪崩是全部數(shù)據(jù)。

解決方案

  1. 永不過期:簡單粗暴
  2. 請(qǐng)求限流:
    • 限制請(qǐng)求數(shù)量盐股,常見的限流算法有滑動(dòng)窗口,令牌桶算法和漏桶算法耻卡,或者直接使用隊(duì)列疯汁、加鎖(信號(hào)量)等
    • 限制數(shù)據(jù)庫的每秒請(qǐng)求數(shù),避免數(shù)據(jù)庫掛掉卵酪。對(duì)于被限流的請(qǐng)求幌蚊,采用服務(wù)降級(jí)處理,比如提供默認(rèn)的值溃卡,或者空白值
  3. 本地緩存:使用 LRU 做二級(jí)緩存

擴(kuò)展 - 服務(wù)雪崩

在微服務(wù)架構(gòu)中溢豆,我們將業(yè)務(wù)拆分成一個(gè)個(gè)的服務(wù),服務(wù)與服務(wù)之間可以相互調(diào)用瘸羡,但是由于網(wǎng)絡(luò)原因或者自身的原因漩仙,服務(wù)并不能保證服務(wù)的100%可用,如果單個(gè)服務(wù)出現(xiàn)問題,調(diào)用這個(gè)服務(wù)就會(huì)出現(xiàn)網(wǎng)絡(luò)延遲队他,此時(shí)若有大量的網(wǎng)絡(luò)涌入卷仑,會(huì)形成任務(wù)堆積,最終導(dǎo)致服務(wù)癱瘓麸折。

由于服務(wù)與服務(wù)之間的依賴性锡凝,故障會(huì)傳播,會(huì)對(duì)整個(gè)微服務(wù)系統(tǒng)造成災(zāi)難性的嚴(yán)重后果垢啼,這就是服務(wù)故障的“雪崩效應(yīng)” 窜锯。

image

雪崩發(fā)生的原因多種多樣,有不合理的容量設(shè)計(jì)芭析,或者是高并發(fā)下某一個(gè)方法響應(yīng)變慢锚扎,亦或是某臺(tái)機(jī)器的資源耗盡。我們無法完全杜絕雪崩源頭的發(fā)生放刨,只有做好足夠的容錯(cuò)工秩,保證在一個(gè)服務(wù)發(fā)生問題,不會(huì)影響到其它服務(wù)的正常運(yùn)行进统。也就是"雪落而不雪崩"助币。

5.2 常見的容錯(cuò)方案

容錯(cuò)說白了就是保護(hù)自己不被豬隊(duì)友拖垮的一些措施,下面介紹常見的服務(wù)容錯(cuò)思路和組件螟碎。

常見的容錯(cuò)思路

1眉菱、隔離

它是指將系統(tǒng)按照一定的原則劃分為若干個(gè)服務(wù)模塊,各個(gè)模塊之間相對(duì)獨(dú)立掉分,無強(qiáng)依賴俭缓。當(dāng)有故障發(fā)生時(shí),能將問題和影響隔離在某個(gè)模塊內(nèi)部酥郭,而不擴(kuò)散風(fēng)險(xiǎn)华坦,不波及其它模塊,不影響整體的系統(tǒng)服務(wù)不从。常見的隔離方式有:線程池隔離和信號(hào)量隔離惜姐。

image

Hystrix線程隔離技術(shù)解析-線程池

Hystrix線程隔離技術(shù)解析-信號(hào)量

2、超時(shí)

在上游服務(wù)調(diào)用下游服務(wù)的時(shí)候椿息,設(shè)置一個(gè)最大響應(yīng)時(shí)間歹袁,如果超過這個(gè)時(shí)間,下游未作出反應(yīng)寝优,就斷開請(qǐng)求条舔,釋放掉線程。

image
3乏矾、限流

限流就是限制系統(tǒng)的輸入和輸出流量已達(dá)到保護(hù)系統(tǒng)的目的孟抗。為了保證系統(tǒng)的穩(wěn)固運(yùn)行迁杨,一旦達(dá)到的需要限制的閾值,就需要限制流量并采取少量措施以完成限制流量的目的夸浅。

image
4仑最、熔斷

在互聯(lián)網(wǎng)系統(tǒng)中,當(dāng)下游服務(wù)因訪問壓力過大而響應(yīng)變慢或失敗帆喇,上游服務(wù)為了保護(hù)系統(tǒng)整 體的可用性警医,可以暫時(shí)切斷對(duì)下游服務(wù)的調(diào)用。這種犧牲局部坯钦,保全整體的措施就叫做熔斷预皇。

image

服務(wù)熔斷一般有三種狀態(tài):

  • 熔斷關(guān)閉狀態(tài)(Closed) :服務(wù)沒有故障時(shí),熔斷器所處的狀態(tài)婉刀,對(duì)調(diào)用方的調(diào)用不做任何限制
  • 熔斷開啟狀態(tài)(Open) :后續(xù)對(duì)該服務(wù)接口的調(diào)用不再經(jīng)過網(wǎng)絡(luò)吟温,直接執(zhí)行本地的fallback方法
  • 半熔斷狀態(tài)(Half-Open):嘗試恢復(fù)服務(wù)調(diào)用,允許有限的流量調(diào)用該服務(wù)突颊,并監(jiān)控調(diào)用成功率鲁豪。如果成功率達(dá)到預(yù)期,則說明服務(wù)已恢復(fù)律秃,進(jìn)入熔斷關(guān)閉狀態(tài)爬橡;如果成功率仍舊很低,則重新進(jìn)入熔斷關(guān)閉狀態(tài)棒动。
5糙申、降級(jí)

降級(jí)其實(shí)就是為服務(wù)提供一個(gè)托底方案,一旦服務(wù)無法正常調(diào)用船惨,就使用托底方案柜裸。

image

常見的容錯(cuò)組件

Hystrix:

Hystrix是由Netflix開源的一個(gè)延遲和容錯(cuò)庫,用于隔離訪問遠(yuǎn)程系統(tǒng)粱锐、服務(wù)或者第三方庫疙挺,防止級(jí)聯(lián)失敗,從而提升系統(tǒng)的可用性與容錯(cuò)性怜浅。

Resilience4J:

Resilicence4J一款非常輕量衔统、簡單,并且文檔非常清晰海雪、豐富的熔斷工具,這也是Hystrix官方推薦的替代產(chǎn)品舱殿。不僅如此奥裸,Resilicence4j還原生支持Spring Boot 1.x/2.x,而且監(jiān)控也支持和 prometheus等多款主流產(chǎn)品進(jìn)行整合沪袭。

Sentinel:

Sentinel 是阿里巴巴開源的一款斷路器實(shí)現(xiàn)湾宙,本身在阿里內(nèi)部已經(jīng)被大規(guī)模采用樟氢,非常穩(wěn)定。

Sentinel Hystrix resilience4j
隔離策略 信號(hào)量隔離(并發(fā)線程數(shù)限流) 線程池隔離/信號(hào)量隔離 信號(hào)量隔離
熔斷降級(jí)策略 基于響應(yīng)時(shí)間侠鳄、異常比率埠啃、異常數(shù)等 異常比率模式、超時(shí)熔斷 基于異常比率伟恶、響應(yīng)時(shí)間
實(shí)時(shí)統(tǒng)計(jì)實(shí)現(xiàn) 滑動(dòng)窗口(LeapArray) 滑動(dòng)窗口(基于 RxJava) Ring Bit Buffer
動(dòng)態(tài)規(guī)則配置 支持多種配置源 支持多種數(shù)據(jù)源 有限支持
擴(kuò)展性 豐富的 SPI 擴(kuò)展接口 插件的形式 接口的形式
基于注解的支持 支持 支持 支持
限流 基于 QPS碴开,支持基于調(diào)用關(guān)系的限流 有限的支持 Rate Limiter
集群流量控制 支持 不支持 不支持
流量整形 支持預(yù)熱模式、勻速排隊(duì)模式等多種復(fù)雜場(chǎng)景 不支持 簡單的 Rate Limiter 模式
系統(tǒng)自適應(yīng)保護(hù) 支持 不支持 不支持
控制臺(tái) 提供開箱即用的控制臺(tái)博秫,可配置規(guī)則潦牛、查看秒級(jí)監(jiān)控、機(jī)器發(fā)現(xiàn)等 簡單的監(jiān)控查看 不提供控制臺(tái)挡育,可對(duì)接其它監(jiān)控系統(tǒng)
多語言支持 Java / C++ Java Java
開源社區(qū)狀態(tài) 活躍 停止維護(hù) 較活躍

參考文章

緩存三大問題及解決方案

緩存穿透巴碗,緩存擊穿,緩存雪崩解決方案分析

*緩存失效的場(chǎng)景

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末即寒,一起剝皮案震驚了整個(gè)濱河市橡淆,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌母赵,老刑警劉巖逸爵,帶你破解...
    沈念sama閱讀 217,907評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異市咽,居然都是意外死亡痊银,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門施绎,熙熙樓的掌柜王于貴愁眉苦臉地迎上來溯革,“玉大人,你說我怎么就攤上這事谷醉≈孪。” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵俱尼,是天一觀的道長抖单。 經(jīng)常有香客問我,道長遇八,這世上最難降的妖魔是什么矛绘? 我笑而不...
    開封第一講書人閱讀 58,586評(píng)論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮刃永,結(jié)果婚禮上货矮,老公的妹妹穿的比我還像新娘。我一直安慰自己斯够,他們只是感情好囚玫,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評(píng)論 6 392
  • 文/花漫 我一把揭開白布喧锦。 她就那樣靜靜地躺著,像睡著了一般抓督。 火紅的嫁衣襯著肌膚如雪燃少。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,488評(píng)論 1 302
  • 那天铃在,我揣著相機(jī)與錄音阵具,去河邊找鬼。 笑死涌穆,一個(gè)胖子當(dāng)著我的面吹牛怔昨,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播宿稀,決...
    沈念sama閱讀 40,275評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼趁舀,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了祝沸?” 一聲冷哼從身側(cè)響起矮烹,我...
    開封第一講書人閱讀 39,176評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎罩锐,沒想到半個(gè)月后奉狈,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,619評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡涩惑,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評(píng)論 3 336
  • 正文 我和宋清朗相戀三年仁期,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片竭恬。...
    茶點(diǎn)故事閱讀 39,932評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡跛蛋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出痊硕,到底是詐尸還是另有隱情赊级,我是刑警寧澤,帶...
    沈念sama閱讀 35,655評(píng)論 5 346
  • 正文 年R本政府宣布岔绸,位于F島的核電站理逊,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏盒揉。R本人自食惡果不足惜晋被,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評(píng)論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望刚盈。 院中可真熱鬧墨微,春花似錦、人聲如沸扁掸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽谴分。三九已至锈麸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間牺蹄,已是汗流浹背忘伞。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評(píng)論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留沙兰,地道東北人氓奈。 一個(gè)月前我還...
    沈念sama閱讀 48,095評(píng)論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像鼎天,于是被迫代替她去往敵國和親舀奶。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評(píng)論 2 354

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