今晚無聊,躺在床上,在刷技術文章時,看見了一篇關於redis緩存的文章 寫的蠻好,這也就引起了我對於redis思考!
不如往深了說 引起了我對於追求探索技術本質的一些思考 平時在網上刷到很多關於redis的文章,我也在項目中經常用到redis這個緩存數據庫 記得自己初學redis時 總是糾結技術如果去學 但是隨着閱歷以及學習能力和經驗的提高 自己也對技術也有一些悟出來的道理 或者說是如何學好技術 往后有時間或者哪天心血來潮了寫一篇關於自己對於技術的認知
還是進入主題,在網上經常刷到關於redis的文章,自己也經常在項目中用到redis,但是自己從來沒有太過深究redis,心里老覺得不得勁 於是今晚就心血來潮了寫一篇關於自己對redis的一些思考
這里我就不說redis是干什么的了,如果不知道看下我之前寫的redis文章,這些文章中也有官網的內容 因為我也是從官網學的)
1.聊聊redis緩存穿透問題
如何理解緩存穿透呢?就是當請求訪問過來時 先去查詢redis緩存,如果緩存中沒有, 再去查詢mysql數據庫, 然后mysql數據庫返回數據到redis緩存中, redis接收數據並把數據存儲起來, 這樣當下次請求過來時,服務端就直接查詢redis緩存了並返回給客戶端,不必再去查詢mysql,緩解了數據庫壓力,並提高了效率
這是我們的正常情況對不對!
但但但但但但但是......有沒有想過一個問題,如果是黑客惡意攻擊,客戶端發起的請求中的數據,我們緩存中不僅沒有,就連我們的mysql中也沒有! 這下完犢子了 這下客戶端只要重復的發送這個請求,所有的請求會經過redis后然后再來請求我們的mysql,因為我們數據庫中沒有呀,所以查詢不到,也沒有數據往redis中存),這就是緩存穿透
那么如果是一個黑客惡意發起請求,mysql就有可能在長時間內持續承受大量的請求,mysql這時候心里很苦,很快就會撂挑子不干了,直接宕機,(接下來,整個系統宕機,然后你就抓緊刪庫跑路吧,(逃,
如果是大型項目的話,這個損失是很大的
那我們就要像羔羊一樣任人宰割嗎?NONONO,redis還有一個好兄弟,這個好兄弟叫作布隆過濾器
這個好兄弟可以存放大數據量,(偷偷告訴你,存放大數據量是他的優點,但是他也有缺點,就是查詢到的結果不一定准確,0代表一定沒有,1代表不一定有,布隆過濾器這位redis的好兄弟我這里就不介紹了,只介紹這位好兄弟如何仗義行俠幫助我們的redis
在中間加了這位好兄弟,那么當請求進來后,會首先經過我們的布隆過濾器,這個好兄弟先判斷這個數據存不存在,若判斷不存在直接丟棄請求,若這個數據存在再去進行redis查詢,然后執行下一步,最后響應,有了這位好兄弟,我們就可以講數據庫中所有的查詢條件,放入布隆過濾器中,所有的請求先交給這位好兄弟來處理(這位好兄弟是有那么一點不靠譜,但是大體上並不影響
其實還有一種解決方案是把查詢到的空值的key緩存起來並設置過期時間,但是會有一種弊端,就是如何發起大量的請求,那豈不是要接收多少空值的key,都要存在redis中,redis是內存數據庫,內存不要錢嗎?而且遭到惡意攻擊,能有多大內存和黑客剛呢?
具體場景具體用法:
- 如果空值的key少可以考慮緩存起來
- 如果空值的key多並且不重復,還是讓布隆過濾器這位好兄弟來拔刀相助比較好
2.聊聊redis緩存雪崩問題
緩存雪崩可以這樣理解,雪崩雪崩嘛!這些緩存就像雪一樣發生了崩塌,緩存是存在於我們的redis這位好兄弟這里的,這位好兄弟平常管理着這些緩存,加入哪一天這兄弟不高興了,撒手不干了,宕機),那豈不是這些緩存數據又沒了,當請求來臨時又要mysql兄弟處理了,mysql兄弟看到這么些請求過來淦它,心里直發怵啊!簡直是瑟瑟發抖,造成了結果就是數據庫崩潰,系統崩潰 這就是我們緩存雪崩,簡單來說redis宕機了
解決方案也很簡單,簡單粗暴,一個不行來倆甚至更多,一節更比六節強,搭建redis集群然后交給hystrix來監控
3.聊聊緩存擊穿問題
緩存擊穿這個和緩存穿透字面上有點像,但是區別在於緩存穿透是數據中沒有這個key,但是緩存擊穿是數據中有這個key,並且我們要把這個key緩存到redis中,
比如淘寶雙11,並不是所有的商品都要搞活動,只是一部分搞活動,那么這一部分商品在活動開始時,必然會有大量的用戶去搶購,大量的請求),這時候如果我們的數據在mysql中,mysql必然不干了,mysql這位兄弟內存又要罵娘了,那么我們就需要redis來救場,提前把這些熱點的key(需要搞活動的商品)緩存到redis中,當活動開始時直接去淦redis,沒事redis扛得住,這樣就解決了這個問題
但但但但但但是.......如果這個key突然在用戶還沒搶購完的時候,很媽離譜就過期了!那么完犢子,mysql又要罵娘了
這就是緩存擊穿(熱點key過期問題)
解決方案:
- 熱點key竟然要媽離譜過期,我們在設置熱點key時讓這個bi永不過期就完事了,簡單粗暴
- 互斥鎖,當第一個查詢數據庫的請求發起時,給緩存中這個數據上鎖,其他請求這個key等待,當第一個查詢數據庫打請求完成后解鎖,其他請求直接從緩存中查