文章目錄
- 1.緩存穿透
- 2.緩存雪崩
- 3.緩存擊穿
- 3.1 互斥鎖
- 3.2 基于邏輯過期
1.緩存穿透
解決辦法
寫入NULL值到Redis緩存,以后就會命中Redis的控制緩存而不會出現請求直接打到數據庫的問題!
代碼
2.緩存雪崩
這個概念很好理解,雪崩就是無數的小雪花結構突然因為外界傳遞的巨大能量而受到破壞,因此無數雪花結構崩潰導致雪崩,這里緩存里面的key也是一樣的,大量的key同時失效導致大量請求打到數據庫,導致數據庫崩潰!
3.緩存擊穿
3.1 互斥鎖
利用到了Redis的setnx指令,這種指令設置的key是只有該key不存在時才會被修改成功,如果該key已經存在,則無法修改該key。利用該特性,如果大量的線程來到獲取該key并修改該key為1,那么實際上只有1個key才會被修改成功,并且java中提供了相應的函數提供此功能,如果修改成功,那么返回True,如果修改失敗,那么返回false,根據此特性,如果我們使用該函數如果返回False那就是獲取互斥鎖失敗,如果True那就是獲取互斥鎖成功!接著我們可以直接使其他所有的相關線程Sleep就完事兒了,等到獲取互斥鎖成功的線程執行完重構緩存的命令完了之后再來訪問!原來成功獲取鎖的線程就直接返回舊的緩存數據即可!這個就是互斥鎖原理!
3.2 基于邏輯過期
邏輯過期的應用場景是對于熱點Key的訪問,比如商家做活動的時候,系統里面有經常訪問到的key,這種key就是熱點key。
邏輯過期給出的解決方案:
在邏輯過期的解決方案里面,熱點key的緩存的TTL都是直接設置為-1的,即永久保存在Redis中,但是這樣我們如何區分這些個熱點key有無過期呢?于是我們設置了expire字段,標記他有無過期,如果當前時間在這個expire之前,那么就是該熱點key沒過期,直接去做緩存重建,重置熱點key的expire(在原來expire過期時間上再次加上30分鐘),如果過期了,那就直接返回舊的緩存數據,獲取鎖完成緩存重建,用線程池里面的線程完成緩存重建!這樣無論如何都能保證到熱點key永不過期,永遠不會說是熱點key過期了的瞬間又瞬間來了大量的請求打到后臺數據庫導致數據庫宕機!
一般來說在這套流程里面,緩存都是命中的,如果沒命中,只能說明這個key不是熱點key,中了就是熱點key。因為我們的Redis都是提前緩存好了許多的熱點key的,熱點key才會命中,冷門key就沒命中,因為冷門key不在Redis里面。