目前的互聯網系統沒有幾個不使用緩存的, 但是只要使用緩存的話就會面臨這幾個問題, 如使用redis緩存技術, 可能會遇到緩存的雪崩, 穿透, 以及擊穿.
首先來看一個簡單的正常緩存流程:
基於上面的流程,我們來看一下什么是redis的緩存雪崩, 穿透, 擊穿?
舉個例子, 在JD618的時候, 點進去進入到它的首頁, 這個首頁在618的時候訪問量是非常大的, 所以很多的數據是放到redis里面去緩存起來, 對應redis的100key, 然后后台人員設置的key的失效時間是三個小時, 當這個618期間, 購物車超過三小時之后, 這個首頁的redis緩存在一瞬間全部失效, 導致所有的請求都打到了這個數據庫上, 造成數據庫的響應不及時掛掉, 這個時候, 首頁就沒辦法再繼續對外提供服務. 這種現象就是緩存雪崩.
解決方案:
a.設置這個緩存的失效時間, 讓它不要在同一時間失效, 在我們設置這個緩存的時候, 隨機初始化這個失效時間, 這樣的話所有的緩存就不會在同一時間失效, 把所有的請求都打到數據庫上.
b.這個redis一般都是集群部署, 我們把這些熱點的key放到不同的節點上去, 讓這些熱點的緩存, 平均的分布在這個不同的redis節點上.
c.還有最暴力的方法就是不設置這個緩存失效的時間, 讓它永遠不失效.
d.
舉個例子, 比如某個網站非常的火爆, 動了某些人的蛋糕, 然后遭到瘋狂的攻擊, 他的攻擊手段就是采用這個緩存穿透, 大家都知道數據庫主鍵從0開始遞增, 沒有負數, 那么這個黑客就利用這一點, 他不斷的利用這個id小於零的這個參數給我發請求, 我把數據庫里面,所有的數據都放到了redis緩存中去,但是他用id小於零的數來請求, redis里面並沒有這個id小於零的數據, 這樣的話redis就查不到這個結果, 一旦這個redis 查不到這個結果, 就會去數據庫中去查, 造成這個請求不斷的打到這個數據庫上, 因為中間redis這層不能攔截這樣的數據, 這個redis直接被這種數據給穿透了直接穿透到數據庫里面. 這種現象就是緩存穿透. redis和數據庫中都沒有這樣的數據, 一般出現這種情況, 都是一些不正常的用戶.
解決方案:
a.如果這個請求穿透了這個redis, 直接到這個數據庫中, 我數據庫無論查出什么結果, 是空的還是有值, 都會緩存到redis里去, 這樣他下次用同一個參數來發請求的時候, 就不會穿透這個redis.
b.但是他可能換不同的參數, 這個解決方式就是把他這個ip拉黑.
c.但是他也可能換不同的ip, 然后第三個, 就是對參數的合法性校驗, 在判斷這個參數不合法的時候, 直接return掉.
d.
舉個列子, 東哥在618的時候想搞一個噱頭, 把他自己珍藏多年的酒拿出來拍賣, 然后有非常多的人對這個酒非常的感興趣, 在9點的時候准時拍賣這個鞋, 然后某個程序員就把酒的數據放到了redis緩存里, 對應redis一個緩存的key, 拍賣的時候呢大家都非常的熱情, 一直拍賣了四小時還沒有結束這個拍賣, 但是這個酒對應的緩存key, 他的失效時間是四個半小時, 當大家拍賣到四個半小時的時候, 這個酒的緩存key突然失效了, 導致大量的拍賣請求在redis里面查詢不到這個數據, 這些請求就會直接打到這個數據庫,上面去, 造成這個數據庫響應不及時,掛掉. 這個案例呢就是redis的緩存擊穿.
解決方式:
a.首先想到的是讓這個緩存永遠不過期, 那這個方式肯定不太好.
b.使用分布式鎖, 如果是單體應用的話, 就可以使用這個互斥鎖.
覺得此文不錯的,點贊轉發,本人非常感謝!