一次分清緩存穿透,緩存擊穿比吭,緩存雪崩

如果數(shù)據(jù)庫查詢壓力過大怎么辦绽族?當(dāng)然是上緩存了。似乎緩存就是為了緩解數(shù)據(jù)庫壓力而生衩藤,那就這樣完了嗎吧慢?自然不是,可曾遇到過面試Redis的時(shí)候經(jīng)常被問什么是緩存穿透赏表,緩存擊穿检诗,這兩者有什么區(qū)別?啊瓢剿,真是頭大逢慌,一字之差。今天小馬就來一起探討下這一塊呀间狂。

Redis為什么快

Redis采用的是基于內(nèi)存的單線程模型的key/value數(shù)據(jù)庫攻泼,由C語言編寫,官方提供的數(shù)據(jù)是可以達(dá)到100000+的QPS(每秒內(nèi)查詢次數(shù))。單線程為什么這么快忙菠?主要還是得益于基于內(nèi)存何鸡,哈希數(shù)據(jù)結(jié)構(gòu)和單線程上。以下引用一段總結(jié)來解釋牛欢。

1骡男、完全基于內(nèi)存,絕大部分請求是純粹的內(nèi)存操作傍睹,數(shù)據(jù)存在內(nèi)存中隔盛,類似于HashMap,HashMap的優(yōu)勢就是查找和操作的時(shí)間復(fù)雜度都是O(1)焰望;

2骚亿、數(shù)據(jù)結(jié)構(gòu)簡單,對數(shù)據(jù)操作也簡單熊赖,Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進(jìn)行設(shè)計(jì)的;

3虑椎、采用單線程震鹉,避免了不必要的上下文切換和競爭條件,也不存在多進(jìn)程或者多線程導(dǎo)致的切換而消耗 CPU捆姜,不用去考慮各種鎖的問題传趾,不存在加鎖釋放鎖操作,沒有因?yàn)榭赡艹霈F(xiàn)死鎖而導(dǎo)致的性能消耗泥技;

4浆兰、使用多路I/O復(fù)用模型,非阻塞IO珊豹◆こ剩“多路”指的是多個(gè)網(wǎng)絡(luò)連接,“復(fù)用”指的是復(fù)用同一個(gè)線程店茶;

5蜕便、使用底層模型不同,它們之間底層實(shí)現(xiàn)方式以及與客戶端之間通信的應(yīng)用協(xié)議不一樣贩幻,Redis直接自己構(gòu)建了VM 機(jī)制 轿腺,因?yàn)橐话愕南到y(tǒng)調(diào)用系統(tǒng)函數(shù)的話,會(huì)浪費(fèi)一定的時(shí)間去移動(dòng)和請求丛楚;

緩存穿透

啊族壳,查了一下百度百科,似乎沒有相關(guān)的解釋趣些,那只能自己來了仿荆。緩存穿透就是如果請求帶著id過來了,像查詢id=-1的數(shù)據(jù),于是緩存里自然沒有該數(shù)據(jù)赖歌,因?yàn)閿?shù)據(jù)庫本來也就沒有該數(shù)據(jù)枉圃。那這個(gè)就有趣了,如果不斷大量惡意請求庐冯,那就是直接繞過緩存孽亲,一直在查數(shù)據(jù)庫,給數(shù)據(jù)庫造成極大的壓力展父,這就是緩存穿透返劲。

有了問題自然就要想法子解決,提供參考如下:

1栖茉、在邏輯代碼處做一層請求校驗(yàn)篮绿,例如,id的請求范圍校驗(yàn)吕漂。如果請求的參數(shù)不符合規(guī)矩那就直接拒絕請求了亲配,連緩存都拒絕請求了更別說請求到數(shù)據(jù)庫了;

2惶凝、盡量壞數(shù)據(jù)也做緩存吼虎。比如惡意請求的參數(shù)緩存和數(shù)據(jù)庫庫都獲取不到數(shù)據(jù)一次就直接緩存為壞數(shù)據(jù)一段時(shí)間(比如有一個(gè)緩存池key都為bad_id系列,id請求過來后先查詢key=bad_id系列是否有數(shù)據(jù)苍鲜,沒有的話再請求key=id的緩存數(shù)據(jù))思灰,這樣就可以緩解惡意請求帶來的壓力;

3混滔、那如果不是惡意請求洒疚,比如正常id=1的請求,此時(shí)剛好緩存沒數(shù)據(jù)坯屿,數(shù)據(jù)庫也查不到數(shù)據(jù)時(shí)油湖,也是建議緩存處理,如處理為key=>null愿伴。但這個(gè)緩存時(shí)間要根據(jù)實(shí)際業(yè)務(wù)情況設(shè)置肺魁,不宜過長,比如30秒隔节,否則會(huì)影響正常情況的獲榷炀(比如緩存為null期間數(shù)據(jù)庫已經(jīng)有寫入相關(guān)參數(shù)的數(shù)據(jù)了,此時(shí)就出問題了)怎诫。

4瘾晃、布隆過濾器』眉耍可以使用布隆過濾器解決緩存穿透的問題蹦误,把已存在數(shù)據(jù)的key存在布隆過濾器中劫拢。當(dāng)有新的請求時(shí),先到布隆過濾器中查詢是否存在强胰,如果不存在該條數(shù)據(jù)直接返回舱沧;如果存在該條數(shù)據(jù)再查詢緩存查詢數(shù)據(jù)庫。這個(gè)等下詳細(xì)討論偶洋,通俗理解為熟吏,當(dāng)布隆過濾器說,某種東西存在時(shí)玄窝,這種東西可能不存在牵寺;當(dāng)布隆過濾器說,某種東西不存在時(shí)恩脂,那么這種東西一定不存在帽氓。比如布隆還用在了識(shí)別垃圾郵箱的功能上。

緩存擊穿

緩存擊穿就是當(dāng)請求參數(shù)過來俩块,緩存中的數(shù)據(jù)瞬間過期黎休,此時(shí)并發(fā)量又大,全部請求直接同時(shí)轉(zhuǎn)為去請求數(shù)據(jù)庫玉凯,瞬間給數(shù)據(jù)庫帶來巨大壓力奋渔。

參考的解決方案自然也有:

1、設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期壮啊。這個(gè)法子最為粗暴了。

2撑蒜、加互斥鎖歹啼。就是同一時(shí)間只能有一個(gè)請求去查詢DB更新緩存。然后其他請求再從緩存中取數(shù)據(jù)座菠。代碼實(shí)現(xiàn)就是狸眼,對緩存過期后去請求數(shù)據(jù)庫的操作加互斥鎖,其他獲取不到鎖的請求直接等待(sleep)數(shù)秒后再去重新請求獲取數(shù)據(jù)的方法浴滴,自然就能從緩存取數(shù)據(jù)了拓萌,真是智慧。

3升略、將同一熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存節(jié)點(diǎn)中(比如將key哈希分散存儲(chǔ)微王,如id_hash(openid),單獨(dú)設(shè)置過期時(shí)間)品嚣,這樣即可分散熱key對redis的壓力也可避免同一時(shí)間過期后大量請求一起同時(shí)涌向數(shù)據(jù)庫查詢數(shù)據(jù)炕倘。

緩存穿透和擊穿的區(qū)別

這兩者的區(qū)別上面已經(jīng)很清晰了,總結(jié)一下翰撑,穿透就緩存無數(shù)據(jù)數(shù)據(jù)庫也無數(shù)據(jù)罩旋,擊穿就是緩存無數(shù)據(jù)數(shù)據(jù)庫有數(shù)據(jù)。穿透一般是攻擊行為導(dǎo)致,擊穿很可能就是緩存處理不當(dāng)導(dǎo)致涨醋。透為無則通透瓜饥,擊為有則擊之。無則通透浴骂,有則擊之乓土,哈哈,這是小馬的口訣靠闭。

緩存雪崩

啊帐我,剛理清擊穿和穿透,又來一個(gè)雪崩愧膀,真是頭大拦键。引用別人的一段話來解釋,小馬覺得概括得很是精辟易懂檩淋。

緩存雪崩是指緩存中數(shù)據(jù)大批量同時(shí)到過期時(shí)間(比如redis服務(wù)突然掛了后重啟)芬为,而查詢數(shù)據(jù)量巨大,引起數(shù)據(jù)庫壓力過大甚至down機(jī)蟀悦。和緩存擊穿不同的是媚朦,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了日戈,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫询张。

解決方案建議:

1、設(shè)置熱點(diǎn)數(shù)據(jù)永遠(yuǎn)不過期浙炼;

2份氧、緩存數(shù)據(jù)的過期時(shí)間設(shè)置隨機(jī),防止同一時(shí)間大量數(shù)據(jù)過期現(xiàn)象發(fā)生弯屈,就是將緩存過期時(shí)間設(shè)置錯(cuò)開蜗帜;

3、將熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存節(jié)點(diǎn)中资厉,這樣即可防止熱點(diǎn)壓力厅缺,又可以防止緩存同一時(shí)間過期,導(dǎo)致雪崩宴偿。這點(diǎn)和擊穿的預(yù)防方法異曲同工湘捎。

關(guān)于緩存擊穿,緩存穿透酪我,緩存雪崩就到這里了消痛。值得一提的是,布隆過濾器是個(gè)一種比較巧妙的概率型數(shù)據(jù)結(jié)構(gòu)都哭,它可以告訴你某種東西一定不存在或者可能存在秩伞,比較有趣逞带,這點(diǎn)有時(shí)間要細(xì)細(xì)起個(gè)篇幅探討下。謝謝品閱纱新。

原創(chuàng)文章展氓,未經(jīng)允許請勿轉(zhuǎn)載。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末脸爱,一起剝皮案震驚了整個(gè)濱河市遇汞,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌簿废,老刑警劉巖空入,帶你破解...
    沈念sama閱讀 217,907評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異族檬,居然都是意外死亡歪赢,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,987評論 3 395
  • 文/潘曉璐 我一進(jìn)店門单料,熙熙樓的掌柜王于貴愁眉苦臉地迎上來埋凯,“玉大人,你說我怎么就攤上這事扫尖“锥裕” “怎么了?”我有些...
    開封第一講書人閱讀 164,298評論 0 354
  • 文/不壞的土叔 我叫張陵换怖,是天一觀的道長甩恼。 經(jīng)常有香客問我,道長沉颂,這世上最難降的妖魔是什么媳拴? 我笑而不...
    開封第一講書人閱讀 58,586評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮兆览,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘塞关。我一直安慰自己抬探,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,633評論 6 392
  • 文/花漫 我一把揭開白布帆赢。 她就那樣靜靜地躺著小压,像睡著了一般。 火紅的嫁衣襯著肌膚如雪椰于。 梳的紋絲不亂的頭發(fā)上怠益,一...
    開封第一講書人閱讀 51,488評論 1 302
  • 那天,我揣著相機(jī)與錄音瘾婿,去河邊找鬼蜻牢。 笑死烤咧,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的抢呆。 我是一名探鬼主播煮嫌,決...
    沈念sama閱讀 40,275評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抱虐!你這毒婦竟也來了昌阿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,176評論 0 276
  • 序言:老撾萬榮一對情侶失蹤恳邀,失蹤者是張志新(化名)和其女友劉穎懦冰,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體谣沸,經(jīng)...
    沈念sama閱讀 45,619評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡刷钢,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,819評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了鳄抒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闯捎。...
    茶點(diǎn)故事閱讀 39,932評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖许溅,靈堂內(nèi)的尸體忽然破棺而出瓤鼻,到底是詐尸還是另有隱情,我是刑警寧澤贤重,帶...
    沈念sama閱讀 35,655評論 5 346
  • 正文 年R本政府宣布茬祷,位于F島的核電站,受9級特大地震影響并蝗,放射性物質(zhì)發(fā)生泄漏祭犯。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,265評論 3 329
  • 文/蒙蒙 一滚停、第九天 我趴在偏房一處隱蔽的房頂上張望沃粗。 院中可真熱鬧,春花似錦键畴、人聲如沸最盅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,871評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽涡贱。三九已至,卻和暖如春惹想,著一層夾襖步出監(jiān)牢的瞬間问词,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,994評論 1 269
  • 我被黑心中介騙來泰國打工嘀粱, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留激挪,地道東北人辰狡。 一個(gè)月前我還...
    沈念sama閱讀 48,095評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像灌灾,于是被迫代替她去往敵國和親搓译。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,884評論 2 354