緩存穿透鹦蠕、緩存擊穿冒签、緩存雪崩
1. 緩存穿透
緩存穿透是指緩存和數(shù)據(jù)庫中都沒有的數(shù)據(jù)在抛,而用戶不斷發(fā)起請求,如發(fā)起為id為“-1”的數(shù)據(jù)或id為特別大不存在的數(shù)據(jù)萧恕。這時的用戶很可能是攻擊者刚梭,攻擊會導(dǎo)致數(shù)據(jù)庫壓力過大。
解決方案:
- 接口層增加校驗票唆,如用戶鑒權(quán)校驗朴读,id做基礎(chǔ)校驗,id<=0的直接攔截走趋;(或者使用布隆過濾器在緩存層前攔截非法請求衅金、自動為空值添加黑名單,同時可能要為誤判的記錄添加白名單簿煌,但需要考慮布隆過濾器的維護(hù)氮唯。
- 從緩存取不到的數(shù)據(jù),在數(shù)據(jù)庫中也沒有取到姨伟,這時也可以將key-value對寫為key-null惩琉,緩存有效時間可以設(shè)置短點,如30秒(設(shè)置太長會導(dǎo)致正常情況也沒法使用)夺荒。這樣可以防止攻擊用戶反復(fù)用同一個id暴力攻擊瞒渠。
2. 緩存擊穿
緩存擊穿是指緩存中沒有但數(shù)據(jù)庫中有的數(shù)據(jù)(一般是緩存時間到期),這時由于并發(fā)用戶特別多技扼,同時讀緩存沒讀到數(shù)據(jù)伍玖,又同時去數(shù)據(jù)庫去取數(shù)據(jù),引起數(shù)據(jù)庫壓力瞬間增大剿吻,造成過大壓力窍箍。
解決方案:
設(shè)置熱點數(shù)據(jù)永遠(yuǎn)不過期。
-
加互斥鎖和橙,互斥鎖參考代碼如下:
這是簡化處理仔燕,理論上如果能根據(jù)key值加鎖就更好了,就是線程A從數(shù)據(jù)庫取key1的數(shù)據(jù)并不妨礙線程B取key2的數(shù)據(jù)魔招,上面代碼明顯做不到這點晰搀。
3. 緩存雪崩
緩存雪崩是指緩存中數(shù)據(jù)大批量到過期時間,而查詢數(shù)據(jù)量巨大办斑,引起數(shù)據(jù)庫壓力過大甚至down機(jī)外恕。
和緩存擊穿不同的是杆逗,緩存擊穿指并發(fā)查同一條數(shù)據(jù),緩存雪崩是不同數(shù)據(jù)都過期了鳞疲,很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫罪郊。
解決方案:
- 緩存數(shù)據(jù)的過期時間設(shè)置隨機(jī),防止同一時間大量數(shù)據(jù)過期現(xiàn)象發(fā)生尚洽。
- 如果緩存數(shù)據(jù)庫是分布式部署悔橄,將熱點數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫中。
- 設(shè)置熱點數(shù)據(jù)永遠(yuǎn)不過期腺毫。
緩存雪崩在Redis中的解決方案:
- 事前:Redis 高可用癣疟,主從 + 哨兵,集群潮酒,避免全盤崩潰睛挚。
- 事中:本地 ehcache 緩存 + hystrix 限流 & 降級,避免數(shù)據(jù)庫承受太多壓力崩掉急黎。
- 事后:Redis 持久化扎狱,一旦重啟,自動從磁盤上加載數(shù)據(jù)勃教,快速恢復(fù)緩存數(shù)據(jù)淤击。
上面在Redis中解決緩存雪崩的請求過程:
- 用戶請求先訪問本地緩存,無命中后再訪問 Redis荣回,如果本地緩存和 Redis 都沒有再查數(shù)據(jù)庫遭贸,并把數(shù)據(jù)添加到本地緩存和 Redis;
- 由于設(shè)置了限流心软,一段時間范圍內(nèi)超出的請求走降級處理(返回默認(rèn)值壕吹,或給出友情提示)。
參考文檔:https://blog.csdn.net/kongtiao5/article/details/82771694