緩存處理流程
前臺(tái)請(qǐng)求,后臺(tái)先從緩存中取數(shù)據(jù),取到直接返回結(jié)果,取不到時(shí)從數(shù)據(jù)庫(kù)中取,數(shù)據(jù)庫(kù)取到更新緩存,并返回結(jié)果,數(shù)據(jù)庫(kù)也沒取到,那直接返回空結(jié)果。

緩存穿透
緩存穿透是指緩存和數(shù)據(jù)庫(kù)中都沒有數(shù)據(jù), 用戶不斷發(fā)起請(qǐng)求, 比如id為-1的或者id為特別大不存在的數(shù)據(jù), 這時(shí)候用戶可能是攻擊者, 攻擊會(huì)導(dǎo)致數(shù)據(jù)庫(kù)壓力過大
解決方案:
- 接口層做一些校驗(yàn),id 做基礎(chǔ)校驗(yàn),比如id<= 0de 直接攔截
- 從緩存和數(shù)據(jù)庫(kù)都取不到數(shù)。 這時(shí)候也可以將key-value寫為key-null , 緩存有效時(shí)間設(shè)置短一些。?。ㄔO(shè)置太長(zhǎng)會(huì)導(dǎo)致正常情況也沒有辦法使用)?!∵@樣子可以防止用戶反復(fù)用同一個(gè)id暴力攻擊。
- 使用布隆過濾器,快速判斷key是否在數(shù)據(jù)庫(kù)中存在,不存在直接返回
緩存擊穿
緩存擊穿是指緩存中沒有,但是數(shù)據(jù)庫(kù)中有數(shù)據(jù)(一般是緩存時(shí)間到期), 這時(shí)候有用用戶特別多, 同一個(gè)id同時(shí)讀緩存沒有讀取到數(shù)據(jù), 又同時(shí)去數(shù)據(jù)庫(kù)中讀取數(shù)據(jù), 引起數(shù)據(jù)庫(kù)壓力瞬間增大, 造成過大的壓力
解決方案:
1 設(shè)置熱點(diǎn)數(shù)據(jù)永不過期
2 加互斥鎖

獲取鎖失敗之后過一點(diǎn)點(diǎn)時(shí)間重新去獲取
1)緩存中有數(shù)據(jù),直接走上述代碼13行后就返回結(jié)果了
2)緩存中沒有數(shù)據(jù),第1個(gè)進(jìn)入的線程,獲取鎖并從數(shù)據(jù)庫(kù)去取數(shù)據(jù),沒釋放鎖之前,其他并行進(jìn)入的線程會(huì)等待100ms,再重新去緩存取數(shù)據(jù)。這樣就防止都去數(shù)據(jù)庫(kù)重復(fù)取數(shù)據(jù),重復(fù)往緩存中更新數(shù)據(jù)情況出現(xiàn)。
3)當(dāng)然這是簡(jiǎn)化處理,理論上如果能根據(jù)key值加鎖就更好了,就是線程A從數(shù)據(jù)庫(kù)取key1的數(shù)據(jù)并不妨礙線程B取key2的數(shù)據(jù),上面代碼明顯做不到這點(diǎn)。
緩存雪崩
緩存雪崩是指的是緩存中大批量到過期時(shí)間,然后短時(shí)間查詢數(shù)據(jù)庫(kù)的量巨大, 引起數(shù)據(jù)庫(kù)壓力過大, 甚至宕機(jī)?!『途彺鎿舸┎煌氖牵【彺鎿舸┲覆l(fā)查找同一條數(shù)據(jù), 緩存雪崩是不同數(shù)據(jù)都過期了, 很多數(shù)據(jù)都查不到從而查數(shù)據(jù)庫(kù)。
解決方案:
1 緩存數(shù)據(jù)的過期時(shí)間設(shè)置隨機(jī), 防止同一時(shí)間大量數(shù)據(jù)過期現(xiàn)象發(fā)生
2 如果緩存數(shù)據(jù)庫(kù)是分布式部署, 將熱點(diǎn)數(shù)據(jù)均勻分布在不同的緩存數(shù)據(jù)庫(kù)中
3 設(shè)置熱點(diǎn)數(shù)據(jù)永不過期