一术瓮、Redis的緩存穿透
1康聂、概念:
用戶需要查詢一個數(shù)據(jù),但是redis中沒有(比如說mysql中id=-1的數(shù))胞四,直接去請求MySQL恬汁,當(dāng)很多用戶同時請求并且都么有命中!于是都去請求了持久層的數(shù)據(jù)庫辜伟,那么這樣會給持久層數(shù)據(jù)庫帶來非常大的壓力氓侧。一般出現(xiàn)這樣的情況都不是正常用戶,基本上都是惡意用戶导狡!
2约巷、解決方案
①布隆過濾器:
布隆過濾器是一種數(shù)據(jù)結(jié)構(gòu),對所有可能查詢的參數(shù)以hash形式存儲旱捧,在控制層先進行校驗独郎,不符合則 丟棄,從而避免了對底層存儲系統(tǒng)的查詢壓力枚赡;
因為篇幅原因氓癌,在此不展開講,后面會出單獨的文章來仔細講解布隆過濾器标锄!
②緩存空對象:
當(dāng)存儲層查不到顽铸,即使是空值茁计,我們也將其存儲起來并且在Redis中設(shè)置一個過期時間料皇,之后再訪問這個數(shù)據(jù)將會從Redis中訪問谓松,保護了持久層的數(shù)據(jù)庫!
③存在的問題:
1)如果空值能夠被緩存起來践剂,這就意味著緩存需要更多的空間存儲更多的鍵鬼譬,因為這當(dāng)中可能會有很多 的空值的鍵;
2)即使對空值設(shè)置了過期時間逊脯,還是會存在緩存層和存儲層的數(shù)據(jù)會有一段時間窗口的不一致优质,這對于 需要保持一致性的業(yè)務(wù)會有影響。
注意:緩存穿透前提是:Redis和MySQL中都沒有军洼,然后不停的直接請求MySQL巩螃。
二、Redis的緩存擊穿
1匕争、概念:
是指一個非常熱點的key避乏,在不停的扛著大并發(fā),當(dāng)這個key失效時甘桑,一瞬間大量的請求沖到持久層的數(shù)據(jù)庫中拍皮,就像在一堵墻上某個點鑿開了一個洞!
2跑杭、解決方案:
①設(shè)置熱點key永不過期:
從緩存層面來看铆帽,沒有設(shè)置過期時間,所以不會出現(xiàn)熱點 key 過期后產(chǎn)生的問題德谅。
②加互斥鎖:
在查詢持久層數(shù)據(jù)庫時爹橱,保證了只有一個線程能夠進行持久層數(shù)據(jù)查詢,其他的線程讓它睡眠幾百毫秒窄做,等待第一個線程查詢完會回寫到Redis緩存當(dāng)中宅荤,剩下的線程可以正常查詢Redis緩存,就不存在大量請求去沖擊持久層數(shù)據(jù)庫了浸策!
③缺點:
其實設(shè)置永不過期不合理冯键!
三、Redis的緩存雪崩
1庸汗、概念:
在某一個時間段惫确,緩存的key大量集中同時過期了,所有的請求全部沖到持久層數(shù)據(jù)庫上蚯舱,導(dǎo)致持久層數(shù)據(jù)庫掛掉改化! 范例:雙十一零點搶購,這波商品比較集中的放在緩存枉昏,設(shè)置了失效時間為1個小時陈肛,那么到了零點,這批緩存全部失效了兄裂,而大量的請求過來時句旱,全部沖過了緩存阳藻,沖到了持久層數(shù)據(jù)庫!
2谈撒、解決方案:
①Redis高可用:
搭建Redis集群腥泥,既然redis有可能掛掉,那我多增設(shè)幾臺redis啃匿,這樣一臺掛掉之后其他的還可以繼續(xù)工作蛔外,其實就是搭建的集群。(異地多活K萜埂)
②限流降級:
在緩存失效后夹厌,通過加鎖或者隊列來控制讀數(shù)據(jù)庫寫緩存的線程數(shù)量。比如對 某個key只允許一個線程查詢數(shù)據(jù)和寫緩存裆悄,其他線程等待尊流。
③數(shù)據(jù)預(yù)熱:
數(shù)據(jù)加熱的含義就是在正式部署之前,我先把可能的數(shù)據(jù)先預(yù)先訪問一遍灯帮,這樣部分可能大量訪問的數(shù)據(jù)就會加載到緩存中崖技。在即將發(fā)生大并發(fā)訪問前手動觸發(fā)加載緩存不同的key,設(shè)置不同的過期時間钟哥,讓緩存失效的時間點盡量均勻 迎献。