1.緩存穿透
緩存穿透是指查詢一個(gè)一定不存在的數(shù)據(jù),由于緩存是在不命中時(shí)被動(dòng)寫入的,并且出于容錯(cuò)考慮嚣州,如果從存儲(chǔ)層查不到數(shù)據(jù)就不寫入緩存鲫售,這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請求都要去存儲(chǔ)層查詢,這就失去了緩存的意義该肴。在流量大的時(shí)候情竹,就很有可能使得數(shù)據(jù)庫掛掉,要是有人利用不存在的key攻擊我們的應(yīng)用匀哄,這將成為漏洞秦效。
解決方案
采用布隆過濾器,將所有可能存在的數(shù)據(jù)利用多個(gè)hash函數(shù)存入一個(gè)非常大的bitmap中涎嚼,一個(gè)一定不存在的數(shù)據(jù)將會(huì)被攔截住阱州,從而避免造成底層數(shù)據(jù)庫的查詢壓力。另一個(gè)簡單粗暴的方法是法梯,如果一個(gè)查詢返回的數(shù)據(jù)為空苔货,我們?nèi)稳话堰@個(gè)空結(jié)果進(jìn)行緩存,但是他的過期時(shí)間會(huì)很短立哑,最長不超過5分鐘夜惭。
2.緩存雪崩
緩存雪崩是指在我們在設(shè)置緩存時(shí)采用了相同的過期時(shí)間,導(dǎo)致緩存會(huì)在某一個(gè)時(shí)刻同時(shí)失效铛绰,請求全部轉(zhuǎn)發(fā)到DB,導(dǎo)致DB壓力過重雪崩诈茧。
解決方案
緩存失效時(shí)的雪崩效應(yīng)對底層系統(tǒng)的沖擊非常可怕捂掰。大多數(shù)系統(tǒng)設(shè)計(jì)者考慮用加鎖或者隊(duì)列的方式保證緩存的單線 程(進(jìn)程)寫敢会,從而避免失效時(shí)大量的并發(fā)請求落到底層存儲(chǔ)系統(tǒng)上。這里分享一個(gè)簡單方案就時(shí)講緩存失效時(shí)間分散開这嚣,比如我們可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值走触,比如1-5分鐘隨機(jī),這樣每一個(gè)緩存的過期時(shí)間的重復(fù)率就會(huì)
3.緩存擊穿
對于一些設(shè)置了過期時(shí)間的key疤苹,如果這些key可能會(huì)在某些時(shí)間點(diǎn)被超高并發(fā)地訪問互广,是一種非常“熱點(diǎn)”的數(shù)據(jù)卧土。這個(gè)時(shí)候惫皱,需要考慮一個(gè)問題:緩存被“擊穿”的問題,這個(gè)和緩存雪崩的區(qū)別在于這里針對某一key緩存尤莺,前者則是很多key旅敷。
解決方案
比較常用的做法,是使用mutex颤霎。簡單地來說媳谁,就是在緩存失效的時(shí)候(判斷拿出來的值為空)涂滴,不是立即去load db,而是先使用緩存工具的某些帶成功操作返回值的操作(比如Redis的SETNX或者M(jìn)emcache的ADD)去set一個(gè)mutex key晴音,當(dāng)操作返回成功時(shí)柔纵,再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存;否則锤躁,就重試整個(gè)get緩存的方法搁料。
String get(String key){
String value = redis.get(key);
if(value == null){
if(redis.setnx(key_mutex,"1)){
redis.expire(key_mutex,3*60);
value = db.get(key);
redis.set(key,value);
redis.delete(key_mutex);
}else{
Thread.sleep(50);
get(key);
}
}
}
高并發(fā)下緩存擊穿的解決方案
http://hbxflihua.iteye.com/blog/2354414降低,就很難引發(fā)集體失效的事件系羞。
https://www.cnblogs.com/jinjiangongzuoshi/p/5240280.html