自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

Redis 緩存雪崩、擊穿、穿透

開發(fā) 前端 Redis
提到Redis我相信各位在面試,或者實(shí)際開發(fā)過程中對緩存雪崩,穿透,擊穿也不陌生吧,就算沒遇到過但是你肯定聽過,那三者到底有什么區(qū)別,我們又應(yīng)該怎么去防止這樣的情況發(fā)生呢,我們有請下一位受害者。

正文

提到Redis我相信各位在面試,或者實(shí)際開發(fā)過程中對緩存雪崩,穿透,擊穿也不陌生吧,就算沒遇到過但是你肯定聽過,那三者到底有什么區(qū)別,我們又應(yīng)該怎么去防止這樣的情況發(fā)生呢,我們有請下一位受害者。

面試開始

一個(gè)大腹便便,穿著格子襯衣的中年男子,拿著一個(gè)滿是劃痕的mac向你走來,看著快禿頂?shù)念^發(fā),心想著肯定是尼瑪頂級架構(gòu)師吧!但是我們腹有詩書氣自華,虛都不虛。

[[318845]]

小伙子我看你的簡歷上寫到了Redis,那么我們直接開門見山,直接懟常見的幾個(gè)大問題,Redis雪崩了解么?

帥氣迷人的面試官您好,我了解的,目前電商首頁以及熱點(diǎn)數(shù)據(jù)都會去做緩存 ,一般緩存都是定時(shí)任務(wù)去刷新,或者是查不到之后去更新的,定時(shí)任務(wù)刷新就有一個(gè)問題。

舉個(gè)簡單的例子:如果所有首頁的Key失效時(shí)間都是12小時(shí),中午12點(diǎn)刷新的,我零點(diǎn)有個(gè)秒殺活動大量用戶涌入,假設(shè)當(dāng)時(shí)每秒 6000 個(gè)請求,本來緩存在可以扛住每秒 5000 個(gè)請求,但是緩存當(dāng)時(shí)所有的Key都失效了。此時(shí) 1 秒 6000 個(gè)請求全部落數(shù)據(jù)庫,數(shù)據(jù)庫必然扛不住,它會報(bào)一下警,真實(shí)情況可能DBA都沒反應(yīng)過來就直接掛了。此時(shí),如果沒用什么特別的方案來處理這個(gè)故障,DBA 很著急,重啟數(shù)據(jù)庫,但是數(shù)據(jù)庫立馬又被新的流量給打死了。這就是我理解的緩存雪崩。

我刻意看了下我做過的項(xiàng)目感覺再吊的都不允許這么大的QPS直接打DB去,不過沒慢SQL加上分庫,大表分表可能還還算能頂,但是跟用了Redis的差距還是很大

Redis 緩存雪崩、擊穿、穿透

同一時(shí)間大面積失效,那一瞬間Redis跟沒有一樣,那這個(gè)數(shù)量級別的請求直接打到數(shù)據(jù)庫幾乎是災(zāi)難性的,你想想如果打掛的是一個(gè)用戶服務(wù)的庫,那其他依賴他的庫所有的接口幾乎都會報(bào)錯(cuò),如果沒做熔斷等策略基本上就是瞬間掛一片的節(jié)奏,你怎么重啟用戶都會把你打掛,等你能重啟的時(shí)候,用戶早就睡覺去了,并且對你的產(chǎn)品失去了信心,什么垃圾產(chǎn)品。

面試官摸了摸自己的頭發(fā),嗯還不錯(cuò),那這種情況咋整?你都是怎么去應(yīng)對的?

處理緩存雪崩簡單,在批量往Redis存數(shù)據(jù)的時(shí)候,把每個(gè)Key的失效時(shí)間都加個(gè)隨機(jī)值就好了,這樣可以保證數(shù)據(jù)不會在同一時(shí)間大面積失效,我相信,Redis這點(diǎn)流量還是頂?shù)米〉摹?/p>

  1. setRedis(Key,value,time + Math.random() * 10000); 

如果Redis是集群部署,將熱點(diǎn)數(shù)據(jù)均勻分布在不同的Redis庫中也能避免全部失效的問題,不過本渣我在生產(chǎn)環(huán)境中操作集群的時(shí)候,單個(gè)服務(wù)都是對應(yīng)的單個(gè)Redis分片,是為了方便數(shù)據(jù)的管理,但是也同樣有了可能會失效這樣的弊端,失效時(shí)間隨機(jī)是個(gè)好策略。

或者設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期,有更新操作就更新緩存就好了(比如運(yùn)維更新了首頁商品,那你刷下緩存就完事了,不要設(shè)置過期時(shí)間),電商首頁的數(shù)據(jù)也可以用這個(gè)操作,保險(xiǎn)。

那你了解緩存穿透和擊穿么,可以說說他們跟雪崩的區(qū)別么?

嗯,了解,我先說一下緩存穿透吧,緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù),而用戶不斷發(fā)起請求,我們數(shù)據(jù)庫的 id 都是1開始自增上去的,如發(fā)起為id值為 -1 的數(shù)據(jù)或 id 為特別大不存在的數(shù)據(jù)。這時(shí)的用戶很可能是攻擊者,攻擊會導(dǎo)致數(shù)據(jù)庫壓力過大,嚴(yán)重會擊垮數(shù)據(jù)庫。

小點(diǎn)的單機(jī)系統(tǒng),基本上用postman就能搞死,比如我自己買的阿里云服務(wù)

Redis 緩存雪崩、擊穿、穿透

像這種你如果不對參數(shù)做校驗(yàn),數(shù)據(jù)庫id都是大于0的,我一直用小于0的參數(shù)去請求你,每次都能繞開Redis直接打到數(shù)據(jù)庫,數(shù)據(jù)庫也查不到,每次都這樣,并發(fā)高點(diǎn)就容易崩掉了。

至于緩存擊穿嘛,這個(gè)跟緩存雪崩有點(diǎn)像,但是又有一點(diǎn)不一樣,緩存雪崩是因?yàn)榇竺娣e的緩存失效,打崩了DB,而緩存擊穿不同的是緩存擊穿是指一個(gè)Key非常熱點(diǎn),在不停的扛著大并發(fā),大并發(fā)集中對這一個(gè)點(diǎn)進(jìn)行訪問,當(dāng)這個(gè)Key在失效的瞬間,持續(xù)的大并發(fā)就穿破緩存,直接請求數(shù)據(jù)庫,就像在一個(gè)完好無損的桶上鑿開了一個(gè)洞。

[[318847]]

面試官露出欣慰的眼光,那他們分別怎么解決

緩存穿透我會在接口層增加校驗(yàn),比如用戶鑒權(quán)校驗(yàn),參數(shù)做校驗(yàn),不合法的參數(shù)直接代碼Return,比如:id 做基礎(chǔ)校驗(yàn),id <=0的直接攔截等。

這里我想提的一點(diǎn)就是,我們在開發(fā)程序的時(shí)候都要有一顆“不信任”的心,就是不要相信任何調(diào)用方,比如你提供了API接口出去,你有這幾個(gè)參數(shù),那我覺得作為被調(diào)用方,任何可能的參數(shù)情況都應(yīng)該被考慮到,做校驗(yàn),因?yàn)槟悴幌嘈耪{(diào)用你的人,你不知道他會傳什么參數(shù)給你。

舉個(gè)簡單的例子,你這個(gè)接口是分頁查詢的,但是你沒對分頁參數(shù)的大小做限制,調(diào)用的人萬一一口氣查 Integer.MAX_VALUE 一次請求就要你幾秒,多幾個(gè)并發(fā)你不就掛了么?是公司同事調(diào)用還好大不了發(fā)現(xiàn)了改掉,但是如果是黑客或者競爭對手呢?在你雙十一當(dāng)天就調(diào)你這個(gè)接口會發(fā)生什么,就不用我說了吧。這是之前的Leader跟我說的,我覺得大家也都應(yīng)該了解下。

從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到,這時(shí)也可以將對應(yīng)Key的Value對寫為null、位置錯(cuò)誤、稍后重試這樣的值具體取啥問產(chǎn)品,或者看具體的場景,緩存有效時(shí)間可以設(shè)置短點(diǎn),如30秒(設(shè)置太長會導(dǎo)致正常情況也沒法使用)。

這樣可以防止攻擊用戶反復(fù)用同一個(gè)id暴力攻擊,但是我們要知道正常用戶是不會在單秒內(nèi)發(fā)起這么多次請求的,那網(wǎng)關(guān)層Nginx本渣我也記得有配置項(xiàng),可以讓運(yùn)維大大對單個(gè)IP每秒訪問次數(shù)超出閾值的IP都拉黑。

那你還有別的辦法么?

還有我記得Redis還有一個(gè)高級用法布隆過濾器(Bloom Filter)這個(gè)也能很好的防止緩存穿透的發(fā)生,他的原理也很簡單就是利用高效的數(shù)據(jù)結(jié)構(gòu)和算法快速判斷出你這個(gè)Key是否在數(shù)據(jù)庫中存在,不存在你return就好了,存在你就去查了DB刷新KV再return。

那又有小伙伴說了如果黑客有很多個(gè)IP同時(shí)發(fā)起攻擊呢?這點(diǎn)我一直也不是很想得通,但是一般級別的黑客沒這么多肉雞,再者正常級別的Redis集群都能抗住這種級別的訪問的,小公司我想他們不會感興趣的。把系統(tǒng)的高可用做好了,集群還是很能頂?shù)摹?/p>

緩存擊穿的話,設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期?;蛘呒由匣コ怄i就能搞定了

作為暖男,代碼我肯定幫你們準(zhǔn)備好了

Redis 緩存雪崩、擊穿、穿透

面試結(jié)束

嗯嗯還不錯(cuò),三個(gè)點(diǎn)都回答得很好,今天也不早了,面試就先到這里,明天你再過來二面我繼續(xù)問一下你關(guān)于Redis集群高可用,主從同步,哨兵等知識點(diǎn)的問題。

暈居然還有下一輪面試!(強(qiáng)行下一期的伏筆哈哈)但是為了offer還是得舔,嗯嗯,好的帥氣面試官。

能回答得這么全面這么細(xì)節(jié)還是忍不住點(diǎn)贊

(暗示點(diǎn)贊,每次都看了不點(diǎn)贊,你們想白嫖我么?你們好壞喲,不過我喜歡)

總結(jié)

我們玩歸玩,鬧歸鬧,別拿面試開玩笑。

本文簡單的介紹了,Redis的雪崩,擊穿,穿透,三者其實(shí)都差不多,但是又有一些區(qū)別,在面試中其實(shí)這是問到緩存必問的,大家不要把三者搞混了,因?yàn)榫彺嫜┍?、穿透和擊穿,是緩存最大的問題,要么不出現(xiàn),一旦出現(xiàn)就是致命性的問題,所以面試官一定會問你。

大家一定要理解是怎么發(fā)生的,以及是怎么去避免的,發(fā)生之后又怎么去搶救,你可以不是知道很深入,但是你不能一點(diǎn)都不去想,面試有時(shí)候不一定是對知識面的拷問,或許是對你的態(tài)度的拷問,如果你思路清晰,然后知其然還知其所以然那就很贊,還知道怎么預(yù)防那來上班吧。

最后暖男我繼續(xù)給你們做個(gè)小的技術(shù)總結(jié):

一般避免以上情況發(fā)生我們從三個(gè)時(shí)間段去分析下:

  • 事前:Redis 高可用,主從+哨兵,Redis cluster,避免全盤崩潰。
  • 事中:本地 ehcache 緩存 + Hystrix 限流+降級,避免 MySQL 被打死。
  • 事后:Redis 持久化 RDB+AOF,一旦重啟,自動從磁盤上加載數(shù)據(jù),快速恢復(fù)緩存數(shù)據(jù)。

上面的幾點(diǎn)我會在吊打系列Redis篇全部講一下這個(gè)月應(yīng)該可以吧Redis更完,限流組件,可以設(shè)置每秒的請求,有多少能通過組件,剩余的未通過的請求,怎么辦?走降級!可以返回一些默認(rèn)的值,或者友情提示,或者空白的值。

好處:

數(shù)據(jù)庫絕對不會死,限流組件確保了每秒只有多少個(gè)請求能通過。 只要數(shù)據(jù)庫不死,就是說,對用戶來說,3/5 的請求都是可以被處理的。 只要有 3/5 的請求可以被處理,就意味著你的系統(tǒng)沒死,對用戶來說,可能就是點(diǎn)擊幾次刷不出來頁面,但是多點(diǎn)幾次,就可以刷出來一次。

這個(gè)在目前主流的互聯(lián)網(wǎng)大廠里面是最常見的,你是不是好奇,某明星爆出什么事情,你發(fā)現(xiàn)你去微博怎么刷都空白界面,但是有的人又直接進(jìn)了,你多刷幾次也出來了,現(xiàn)在知道了吧,那是做了降級,犧牲部分用戶的體驗(yàn)換來服務(wù)器的安全,可還行?

責(zé)任編輯:未麗燕 來源: segmentfault.com
相關(guān)推薦

2023-03-10 13:33:00

緩存穿透緩存擊穿緩存雪崩

2019-10-12 14:19:05

Redis數(shù)據(jù)庫緩存

2021-06-05 09:01:01

Redis緩存雪崩緩存穿透

2022-03-08 00:07:51

緩存雪崩數(shù)據(jù)庫

2022-11-18 14:34:28

2019-11-05 14:24:31

緩存雪崩框架

2024-04-18 11:43:28

緩存數(shù)據(jù)庫Redis

2024-04-07 00:00:02

Redis雪崩緩存

2023-04-14 07:34:19

2023-12-06 13:38:00

Redis緩存穿透緩存擊穿

2022-05-27 07:57:20

緩存穿透緩存雪崩緩存擊穿

2020-10-23 10:46:03

緩存雪崩擊穿

2023-11-10 14:58:03

2024-03-12 10:44:42

2023-01-31 08:37:11

緩存穿透擊穿

2020-10-13 07:44:40

緩存雪崩 穿透

2021-12-25 22:28:27

緩存穿透緩存擊穿緩存雪崩

2024-01-19 20:42:08

Redis數(shù)據(jù)庫Key

2022-07-11 07:36:36

緩存緩存雪崩緩存擊穿

2020-03-05 09:09:18

緩存原因方案
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號