《吊打面試官》系列-緩存雪崩、擊穿、穿透

你知道的越多,你不知道的越多java

點贊再看,養成習慣程序員

前言

Redis在互聯網技術存儲方面使用如此普遍,幾乎全部的後端技術面試官都要在Redis的使用和原理方面對小夥伴們進行360°的刁難。做爲一個在互聯網公司面一次拿一次offer的麪霸(請容許我使用一下誇張的修辭手法),戰勝了無數競爭對手,每次都只能看到無數落寞的身影失望的離開,略感愧疚,在一個寂寞難耐的夜晚,我痛定思痛,決定開始寫《吊打面試官》系列,但願能幫助各位讀者之後面試勢如破竹,對面試官進行360°的反擊,吊打問你的面試官,讓一同面試的同僚瞠目結舌,瘋狂收割大廠offer!web

一點感慨

原本都把稿子放到公衆號保存了,洗澡的時候想了一下晚上的比賽,以爲仍是打開電腦寫點東西,跟文章內容不要緊,只是一點我的的感慨,不知道多少小夥伴看了昨天SKT VS G2的比賽,又不知道多少小夥伴還記得Faker手抖的那一幕。面試

不知道大家看了是什麼感覺,我看到他手抖的時候我心裏也抖了,世界賽我支持的都是LPL的隊伍,可是我喜歡李哥這我的,那種對勝利的執著,這麼多年了那種堅持本身的堅持,這麼多利益誘惑在面前卻只想要勝利,這樣的人我好喜歡啊,我想不少人也喜歡。redis

可能就像不少網友說的那樣,英雄遲暮,可是我以爲他仍是有點東西,就像不少人說咱們程序員只能吃年輕飯同樣,可是若是你堅持本身的堅持,作個腹有詩書氣自華的仔,我想最後確定會獲得本身的獲得。算法

好了我也不煽情了,咱們開始講技術吧。數據庫

正文

上一期吊打系列咱們提到了Redis的基礎知識,還沒看的小夥伴能夠回顧一下 後端

《吊打面試官》系列-Redis基礎緩存

那提到Redis我相信各位在面試,或者實際開發過程當中對緩存雪崩穿透擊穿也不陌生吧,就算沒遇到過可是你確定聽過,那三者到底有什麼區別,咱們又應該怎麼去防止這樣的狀況發生呢,咱們有請下一位受害者。安全

面試開始

一個大腹便便,穿着格子襯衣的中年男子,拿着一個盡是劃痕的mac向你走來,看着快禿頂的頭髮,心想着確定是尼瑪頂級架構師吧!可是咱們腹有詩書氣自華,虛都不虛。

小夥子我看你的簡歷上寫到了Redis,那麼咱們直接開門見山,直接懟常見的幾個大問題,Redis雪崩瞭解麼?

帥氣迷人的面試官您好,我瞭解的,目前電商首頁以及熱點數據都會去作緩存 ,通常緩存都是定時任務去刷新,或者是查不到以後去更新的,定時任務刷新就有一個問題。

舉個簡單的例子:若是全部首頁的Key失效時間都是12小時,中午12點刷新的,我零點有個秒殺活動大量用戶涌入,假設當時每秒 6000 個請求,原本緩存在能夠扛住每秒 5000 個請求,可是緩存當時全部的Key都失效了。此時 1 秒 6000 個請求所有落數據庫,數據庫必然扛不住,它會報一下警,真實狀況可能DBA都沒反應過來就直接掛了。此時,若是沒用什麼特別的方案來處理這個故障,DBA 很着急,重啓數據庫,可是數據庫立馬又被新的流量給打死了。這就是我理解的緩存雪崩。

我刻意看了下我作過的項目感受再吊的都不容許這麼大的QPS直接打DB去,不過沒慢SQL加上分庫,大表分表可能還還算能頂,可是跟用了Redis的差距仍是很大

同一時間大面積失效,那一瞬間Redis跟沒有同樣,那這個數量級別的請求直接打到數據庫幾乎是災難性的,你想一想若是打掛的是一個用戶服務的庫,那其餘依賴他的庫全部的接口幾乎都會報錯,若是沒作熔斷等策略基本上就是瞬間掛一片的節奏,你怎麼重啓用戶都會把你打掛,等你能重啓的時候,用戶早就睡覺去了,而且對你的產品失去了信心,什麼垃圾產品。

面試官摸了摸本身的頭髮,嗯還不錯,那這種狀況咋整?你都是怎麼去應對的?

處理緩存雪崩簡單,在批量往Redis存數據的時候,把每一個Key的失效時間都加個隨機值就行了,這樣能夠保證數據不會在同一時間大面積失效,我相信,Redis這點流量仍是頂得住的。

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

若是Redis是集羣部署,將熱點數據均勻分佈在不一樣的Redis庫中也能避免所有失效的問題,不過本渣我在生產環境中操做集羣的時候,單個服務都是對應的單個Redis分片,是爲了方便數據的管理,可是也一樣有了可能會失效這樣的弊端,失效時間隨機是個好策略。

或者設置熱點數據永遠不過時,有更新操做就更新緩存就行了(好比運維更新了首頁商品,那你刷下緩存就完事了,不要設置過時時間),電商首頁的數據也能夠用這個操做,保險。

那你瞭解緩存穿透和擊穿麼,能夠說說他們跟雪崩的區別麼?

嗯,瞭解,我先說一下緩存穿透吧,緩存穿透是指緩存和數據庫中都沒有的數據,而用戶不斷髮起請求,咱們數據庫的 id 都是1開始自增上去的,如發起爲id值爲 -1 的數據或 id 爲特別大不存在的數據。這時的用戶極可能是攻擊者,攻擊會致使數據庫壓力過大,嚴重會擊垮數據庫。

小點的單機系統,基本上用postman就能搞死,好比我本身買的阿里雲服務

像這種你若是不對參數作校驗,數據庫id都是大於0的,我一直用小於0的參數去請求你,每次都能繞開Redis直接打到數據庫,數據庫也查不到,每次都這樣,併發高點就容易崩掉了。

至於緩存擊穿嘛,這個跟緩存雪崩有點像,可是又有一點不同,緩存雪崩是由於大面積的緩存失效,打崩了DB,而緩存擊穿不一樣的是緩存擊穿是指一個Key很是熱點,在不停的扛着大併發,大併發集中對這一個點進行訪問,當這個Key在失效的瞬間,持續的大併發就穿破緩存,直接請求數據庫,就像在一個無缺無損的桶上鑿開了一個洞。

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

緩存穿透我會在接口層增長校驗,好比用戶鑑權校驗,參數作校驗,不合法的參數直接代碼Return,好比:id 作基礎校驗,id <=0的直接攔截等。

這裏我想提的一點就是,咱們在開發程序的時候都要有一顆「不信任」的心,就是不要相信任何調用方,好比你提供了API接口出去,你有這幾個參數,那我以爲做爲被調用方,任何可能的參數狀況都應該被考慮到,作校驗,由於你不相信調用你的人,你不知道他會傳什麼參數給你。

舉個簡單的例子,你這個接口是分頁查詢的,可是你沒對分頁參數的大小作限制,調用的人萬一一口氣查 Integer.MAX_VALUE 一次請求就要你幾秒,多幾個併發你不就掛了麼?是公司同事調用還好大不了發現了改掉,可是若是是黑客或者競爭對手呢?在你雙十一當天就調你這個接口會發生什麼,就不用我說了吧。這是以前的Leader跟我說的,我以爲你們也都應該瞭解下。

從緩存取不到的數據,在數據庫中也沒有取到,這時也能夠將對應Key的Value對寫爲null、位置錯誤、稍後重試這樣的值具體取啥問產品,或者看具體的場景,緩存有效時間能夠設置短點,如30秒(設置太長會致使正常狀況也無法使用)。

這樣能夠防止攻擊用戶反覆用同一個id暴力攻擊,可是咱們要知道正經常使用戶是不會在單秒內發起這麼屢次請求的,那網關層Nginx本渣我也記得有配置項,可讓運維大大對單個IP每秒訪問次數超出閾值的IP都拉黑。

那你還有別的辦法麼?

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

那又有小夥伴說了若是黑客有不少個IP同時發起攻擊呢?這點我一直也不是很想得通,可是通常級別的黑客沒這麼多肉雞,再者正常級別的Redis集羣都能抗住這種級別的訪問的,小公司我想他們不會感興趣的。把系統的高可用作好了,集羣仍是很能頂的。

緩存擊穿的話,設置熱點數據永遠不過時。或者加上互斥鎖就能搞定了

做爲暖男,代碼我確定幫大家準備好了

面試結束

嗯嗯還不錯,三個點都回答得很好,今天也不早了,面試就先到這裏,明天你再過來二面我繼續問一下你關於Redis集羣高可用,主從同步,哨兵等知識點的問題。

暈竟然還有下一輪面試!(強行下一期的伏筆哈哈)可是爲了offer仍是得舔,嗯嗯,好的帥氣面試官。

能回答得這麼全面這麼細節仍是忍不住點贊

暗示點贊,每次都看了不點贊,大家想白嫖我麼?大家好壞喲,不過我喜歡

總結

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

本文簡單的介紹了,Redis雪崩擊穿穿透,三者其實都差很少,可是又有一些區別,在面試中其實這是問到緩存必問的,你們不要把三者搞混了,由於緩存雪崩、穿透和擊穿,是緩存最大的問題,要麼不出現,一旦出現就是致命性的問題,因此面試官必定會問你。

你們必定要理解是怎麼發生的,以及是怎麼去避免的,發生以後又怎麼去搶救,你能夠不是知道很深刻,可是你不能一點都不去想,面試有時候不必定是對知識面的拷問,或許是對你的態度的拷問,若是你思路清晰,而後知其然還知其因此然那就很贊,還知道怎麼預防那來上班吧。

最後暖男我繼續給大家作個小的技術總結:

通常避免以上狀況發生咱們從三個時間段去分析下:

  • 事前:Redis 高可用,主從+哨兵,Redis cluster,避免全盤崩潰。

  • 事中:本地 ehcache 緩存 + Hystrix 限流+降級,避免** MySQL** 被打死。

  • 過後:Redis 持久化 RDB+AOF,一旦重啓,自動從磁盤上加載數據,快速恢復緩存數據。

上面的幾點我會在吊打系列Redis篇所有講一下這個月應該能夠吧Redis更完,限流組件,能夠設置每秒的請求,有多少能經過組件,剩餘的未經過的請求,怎麼辦?走降級!能夠返回一些默認的值,或者友情提示,或者空白的值。

好處:

數據庫絕對不會死,限流組件確保了每秒只有多少個請求能經過。 只要數據庫不死,就是說,對用戶來講,3/5 的請求都是能夠被處理的。 只要有 3/5 的請求能夠被處理,就意味着你的系統沒死,對用戶來講,可能就是點擊幾回刷不出來頁面,可是多點幾回,就能夠刷出來一次。

這個在目前主流的互聯網大廠裏面是最多見的,你是否是好奇,某明星爆出什麼事情,你發現你去微博怎麼刷都空白界面,可是有的人又直接進了,你多刷幾回也出來了,如今知道了吧,那是作了降級,犧牲部分用戶的體驗換來服務器的安全,可還行?

說到服務器,最近雙十一,阿里雲的服務器對新用戶頗有好賊便宜

經過個人連接購買,一年最低僅需86塊(新用戶專享,若是不是新用戶的能夠用家裏人的帳號購買),80一年,200三年我以爲跟白嫖差很少,我直接用老媽帳號買了三年的,準備搭建一個小項目玩玩。你們能夠買來玩玩,想看服務器文章的朋友留言給我,能夠的話我會寫一期怎麼利用服務器的文章。

點個人連接去買有優惠喲

好了各位,以上就是這篇文章的所有內容了,能看到這裏的人呀,都是人才,我後面會每週都更新幾篇《吊打面試官》系列和Java技術棧相關的文章。若是你有什麼想知道的,也能夠留言給我,我一有時間就會寫出來,咱們共同進步。

很是感謝靚仔/靚女您能看到這裏,若是這個文章寫得還不錯的話 求點贊 求關注 求分享 求留言 (對我很是有用)各位的支持和承認,就是我創做的最大動力,咱們下篇文章見,拜了個拜!

敖丙 | 文 【原創】


每週都會持續更新《吊打面試官》系列能夠關注個人公衆號第一時間閱讀和催更,也能夠在公衆號回覆【人才】加入人才交流羣一塊兒討論面試題,就業和工做上有什麼問題也能夠直接滴滴我,我也是個新人,不過不影響咱們一塊兒進步,做爲渣男,我給不了你工做,還給不了你溫暖嘛?

相關文章
相關標籤/搜索