緩存雪崩
描述
緩存在同一時間出現(xiàn)大規(guī)模的key失效,進而請求db加載最新數(shù)據(jù),導(dǎo)致db壓力過大,甚者可能導(dǎo)致db宕機。導(dǎo)致key失效的場景:
-
redis宕機; -
緩存key過期時間一致,同時到期失效;
解決方案
過期時間一致問題/redis宕機
- 均勻過期:設(shè)置不同的過期時間;
- 分級緩存:不同層級使用不同的過期時間;
- 熱點數(shù)據(jù)緩存永不過期;
a.物理不過期,針對熱點key不設(shè)置過期時間;
b.邏輯過期,將過期時間存在對應(yīng)的value上,通過異步程序監(jiān)控、同步更新緩存值; - 保證Redis緩存的高可用,防止Redis宕機導(dǎo)致緩存雪崩的問題??梢允褂?主從+ 哨兵,Redis集群來避免 Redis 全盤崩潰的情況。
緩存雪崩發(fā)生,緩解措施
- 通過互斥鎖,控制緩存的重新寫入;
redis.setnx("lock_key", value)
redis.setnx:當緩存lock_key不存在時,設(shè)置lock_key值為value,方法返回結(jié)果1,反之返回0;
即當成功構(gòu)建lock_key緩存時,其他同步線程訪問將會阻塞,保證同一場景同一時間只有一個線程可以執(zhí)行db load操作,并寫入緩存;
- 使用熔斷機制,限流降;
- redis宕機,重啟redis,盡快同步恢復(fù)緩存數(shù)據(jù);
緩存擊穿
描述
單個key緩存失效,并發(fā)請求導(dǎo)致db壓力過大,與緩存雪崩相似,區(qū)別在于雪崩時大批key緩存失效,穿透則時單個key失效
解決方案
- 通過互斥鎖,控制
db.load以及緩存的重新寫入; - 熱點數(shù)據(jù)永不過期(同雪崩一致);
緩存穿透
描述
與緩存擊穿的區(qū)別在于,緩存擊穿是緩存失效,但是db能夠加載到數(shù)據(jù)資源,而緩存穿透則是緩存未找到,db也查詢不到資源。這樣每次訪問緩存,都會去db加載一次不存在的數(shù)據(jù)。當有大量并發(fā)訪問不存在的數(shù)據(jù)時,就會造成db壓力過大,進而導(dǎo)致db崩潰;
解決方案
- 第一次讀取緩存不存在,db查詢不存在后,將key設(shè)置空值、短過期時間,緩存至redis中。這樣做的好處就是,同一時間大量訪問
不能存在數(shù)據(jù)時,能從緩存直接返回控制;缺點就是不存在數(shù)據(jù)key多種多樣時,redis就會存儲了一批沒用的數(shù)據(jù),占用內(nèi)存; - 布隆過濾器。如果布隆過濾器判定某個 key 不存在布隆過濾器中,那么就一定不存在,如果判定某個 key 存在,那么很大可能是存在(存在一定的誤判率)。于是我們可以在緩存之前再加一個布隆過濾器,將數(shù)據(jù)庫中的所有key都存儲在布隆過濾器中,在查詢Redis前先去布隆過濾器查詢 key 是否存在,如果不存在就直接返回,不讓其訪問數(shù)據(jù)庫,從而避免了對底層存儲系統(tǒng)的查詢壓力。
緩存預(yù)熱
描述
緩存預(yù)熱就是系統(tǒng)上線后,將相關(guān)的緩存數(shù)據(jù)直接加載到緩存系統(tǒng),避免在用戶請求的時候,先查詢數(shù)據(jù)庫,然后再將數(shù)據(jù)緩存的問題,用戶直接查詢事先被預(yù)熱的緩存數(shù)據(jù)。
緩存降級
描述
緩存降級是指緩存失效或緩存服務(wù)器掛掉的情況下,不去訪問數(shù)據(jù)庫,直接返回默認數(shù)據(jù)或訪問服務(wù)的內(nèi)存數(shù)據(jù)。降級一般是有損的操作,所以盡量減少降級對于業(yè)務(wù)的影響程度。