【JAVA面試】— 緩存失效、緩存雪崩、緩存穿透、緩存擊穿、緩存并發(fā)?

緩存失效
出現(xiàn)場景:主要因素是高并發(fā)下,我們一般設(shè)定一個緩存的過期時間。并發(fā)過高可能會出現(xiàn)在某一個時間同時生成了很多的緩存,并且過期時間在同一時刻,這個時候就可能引發(fā)——當(dāng)過期時間到后,這些緩存同時失效,請求全部轉(zhuǎn)發(fā)到DB,DB可能會壓力飆升。
處理方法:一個簡單方案就是將緩存失效時間分散開,不要所有緩存時間長度都設(shè)置成5分鐘或者10分鐘;比如我們可以在原有的失效時間基礎(chǔ)上增加一個隨機值,比如1-5分鐘隨機,這樣每一個緩存的過期時間的重復(fù)率就會降低,就很難引發(fā)集體失效的事件。
緩存失效時產(chǎn)生的雪崩效應(yīng),將所有請求全部放在數(shù)據(jù)庫上,這樣很容易就達(dá)到數(shù)據(jù)庫的瓶頸,導(dǎo)致服務(wù)無法正常提供。盡量避免這種場景的發(fā)生。
緩存雪崩
出現(xiàn)場景:大量的key設(shè)置了相同的過期時間,導(dǎo)致緩存在同一時刻全部失效,造成瞬時DB請求量大、壓力驟增,引起雪崩。
處理方法:可以給緩存設(shè)置過期時間時加上一個隨機值時間,使得每個key的過期時間分布開來,不會集中在同一時刻失效。
緩存穿透
出現(xiàn)場景:指查詢一個一定不存在的數(shù)據(jù),由于緩存是不命中時被動寫的,并且出于容錯考慮,如果從存儲層查不到數(shù)據(jù)則不寫入緩存,這將導(dǎo)致這個不存在的數(shù)據(jù)每次請求都要到存儲層去查詢,失去了緩存的意義。當(dāng)在流量較大時,出現(xiàn)這樣的情況,一直請求DB,很容易導(dǎo)致服務(wù)掛掉。
處理方法
1、如果一個查詢返回的數(shù)據(jù)為空(不管是數(shù)據(jù)不存在,還是系統(tǒng)故障),我們?nèi)匀话堰@個空結(jié)果進(jìn)行緩存,但它的過期時間會很短,一般只有幾分鐘。
2、采用布隆過濾器,將所有可能存在的數(shù)據(jù)哈希到一個足夠大的bitmap中,一個一定不存在的數(shù)據(jù)會被這個bitmap攔截掉,從而避免了對底層存儲系統(tǒng)的查詢壓力。
緩存擊穿
出現(xiàn)場景:一個存在的key,在緩存過期的一刻,同時有大量的請求,這些請求都會擊穿到DB,造成瞬時DB請求量大、壓力驟增。
處理方法:在訪問key之前,采用SETNX(set if not exists)來設(shè)置另一個短期key來鎖住當(dāng)前key的訪問,訪問結(jié)束再刪除該短期key。
緩存并發(fā)
出現(xiàn)場景:有時候如果?站并發(fā)訪問?,?個緩存如果失效,可能出現(xiàn)多個進(jìn)程同時查詢DB,同時設(shè)置緩存的情況,如果并發(fā)確實很?,這也可能造成DB壓?過?,還有緩存頻繁更新的 問題
處理方法:對緩存查詢加鎖,如果KEY不存在,就加鎖,然后查DB入緩存,然后解鎖;其他進(jìn)程如果發(fā)現(xiàn)有鎖就等待,然后等解鎖后返回數(shù)據(jù)或者進(jìn)入DB查詢。