
緩存穿透key對(duì)應(yīng)的數(shù)據(jù)在數(shù)據(jù)源并不存在緩存擊穿key對(duì)應(yīng)的數(shù)據(jù)存在但在redis中過(guò)期緩存雪崩key對(duì)應(yīng)的數(shù)據(jù)存在但在redis中過(guò)期針對(duì)很多key緩存抱歉上一版可能因?yàn)榉指粜?對(duì)齊不規(guī)范導(dǎo)致渲染錯(cuò)位。重新給一個(gè)標(biāo)準(zhǔn) Markdown 表格對(duì)比項(xiàng)緩存穿透緩存擊穿緩存雪崩簡(jiǎn)單含義key 對(duì)應(yīng)的數(shù)據(jù)在數(shù)據(jù)源中也不存在緩存和數(shù)據(jù)庫(kù)都查不到某個(gè)熱點(diǎn) key 對(duì)應(yīng)的數(shù)據(jù)存在但該 key 在 Redis 中過(guò)期很多 key 對(duì)應(yīng)的數(shù)據(jù)存在但大量 key 在 Redis 中同時(shí)過(guò)期或 Redis 整體不可用主要原因請(qǐng)求查詢(xún)不存在的數(shù)據(jù)緩存無(wú)法命中每次都打到數(shù)據(jù)庫(kù)惡意請(qǐng)求可利用這一點(diǎn)壓垮數(shù)據(jù)庫(kù)熱點(diǎn) key 過(guò)期瞬間大量并發(fā)請(qǐng)求同時(shí)打到數(shù)據(jù)庫(kù)大量 key 過(guò)期時(shí)間相同Redis 故障緩存集中失效請(qǐng)求瞬間壓到數(shù)據(jù)庫(kù)解決方式緩存空值并設(shè)置較短過(guò)期時(shí)間布隆過(guò)濾器攔截不存在 key參數(shù)校驗(yàn)接口限流加互斥鎖只放一個(gè)請(qǐng)求回源數(shù)據(jù)庫(kù)熱點(diǎn) key 邏輯過(guò)期熱點(diǎn)數(shù)據(jù)預(yù)熱必要時(shí)熱點(diǎn) key 不設(shè)過(guò)期過(guò)期時(shí)間加隨機(jī)值避免同時(shí)失效Redis 高可用部署多級(jí)緩存限流降級(jí)緩存預(yù)熱一、緩存穿透1.問(wèn)題描述應(yīng)用服務(wù)器壓力變大redis命中率降低一直查詢(xún)數(shù)據(jù)庫(kù)redis查詢(xún)不到數(shù)據(jù)庫(kù)出現(xiàn)很多非正常的url訪問(wèn)key對(duì)應(yīng)的數(shù)據(jù)在數(shù)據(jù)源并不存在每次針對(duì)此key的請(qǐng)求從緩存獲取不到請(qǐng)求都會(huì)壓到數(shù)據(jù)源從而可能壓垮數(shù)據(jù)源。比如用一個(gè)不存在的用戶(hù)id獲取用戶(hù)信息不論緩存還是數(shù)據(jù)庫(kù)都沒(méi)有若黑客利用此漏洞進(jìn)行攻擊可能壓垮數(shù)據(jù)庫(kù)。2.解決方案一個(gè)一定不存在緩存及查詢(xún)不到的數(shù)據(jù)由于緩存是不命中時(shí)被動(dòng)寫(xiě)的并且出于容錯(cuò)考慮如果從存儲(chǔ)層查不到數(shù)據(jù)則不寫(xiě)入緩存這將導(dǎo)致這個(gè)不存在的數(shù)據(jù)每次請(qǐng)求都要到存儲(chǔ)層去查詢(xún)失去了緩存的意義。解決方案1 對(duì)空值緩存如果一個(gè)查詢(xún)返回的數(shù)據(jù)為空不管是數(shù)據(jù)是否不存在我們?nèi)匀话堰@個(gè)空結(jié)果null進(jìn)行緩存設(shè)置空結(jié)果的過(guò)期時(shí)間會(huì)很短最長(zhǎng)不超過(guò)五分鐘2 設(shè)置可訪問(wèn)的名單白名單使用bitmaps類(lèi)型定義一個(gè)可以訪問(wèn)的名單名單id作為bitmaps的偏移量每次訪問(wèn)和bitmap里面的id進(jìn)行比較如果訪問(wèn)id不在bitmaps里面進(jìn)行攔截不允許訪問(wèn)。3 采用布隆過(guò)濾器實(shí)際上是一個(gè)很長(zhǎng)的二進(jìn)制向量(位圖)和一系列隨機(jī)映射函數(shù)哈希函數(shù)。布隆過(guò)濾器可以用于檢索一個(gè)元素是否在一個(gè)集合中。它的優(yōu)點(diǎn)是空間效率和查詢(xún)時(shí)間都遠(yuǎn)遠(yuǎn)超過(guò)一般的算法缺點(diǎn)是有一定的誤識(shí)別率和刪除困難。)將所有可能存在的數(shù)據(jù)哈希到一個(gè)足夠大的bitmaps中一個(gè)一定不存在的數(shù)據(jù)會(huì)被 這個(gè)bitmaps攔截掉從而避免了對(duì)底層存儲(chǔ)系統(tǒng)的查詢(xún)壓力。4 進(jìn)行實(shí)時(shí)監(jiān)控當(dāng)發(fā)現(xiàn)Redis的命中率開(kāi)始急速降低需要排查訪問(wèn)對(duì)象和訪問(wèn)的數(shù)據(jù)和運(yùn)維人員配合可以設(shè)置黑名單限制服務(wù)二、緩存擊穿1.問(wèn)題描述數(shù)據(jù)庫(kù)的訪問(wèn)壓力瞬時(shí)增加redis里面沒(méi)有出現(xiàn)大量的key過(guò)期redis正常運(yùn)行redis的某個(gè)key過(guò)期了大量訪問(wèn)使用這個(gè)keykey對(duì)應(yīng)的數(shù)據(jù)存在但在redis中過(guò)期此時(shí)若有大量并發(fā)請(qǐng)求過(guò)來(lái)這些請(qǐng)求發(fā)現(xiàn)緩存過(guò)期一般都會(huì)從后端DB加載數(shù)據(jù)并回設(shè)到緩存這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把后端DB壓垮。2.解決方案key可能會(huì)在某些時(shí)間點(diǎn)被超高并發(fā)地訪問(wèn)是一種非常“熱點(diǎn)”的數(shù)據(jù)。這個(gè)時(shí)候需要考慮一個(gè)問(wèn)題緩存被“擊穿”的問(wèn)題。解決問(wèn)題1預(yù)先設(shè)置熱門(mén)數(shù)據(jù)在redis高峰訪問(wèn)之前把一些熱門(mén)數(shù)據(jù)提前存入到redis里面加大這些熱門(mén)數(shù)據(jù)key的時(shí)長(zhǎng)2實(shí)時(shí)調(diào)整現(xiàn)場(chǎng)監(jiān)控哪些數(shù)據(jù)熱門(mén)實(shí)時(shí)調(diào)整key的過(guò)期時(shí)長(zhǎng)3使用鎖1.就是在緩存失效的時(shí)候判斷拿出來(lái)的值為空不是立即去load db。2.先使用緩存工具的某些帶成功操作返回值的操作比如Redis的SETNX去set一個(gè)mutex key3.當(dāng)操作返回成功時(shí)再進(jìn)行l(wèi)oad db的操作并回設(shè)緩存,最后刪除mutex key4.當(dāng)操作返回失敗證明有線程在load db當(dāng)前線程睡眠一段時(shí)間再重試整個(gè)get緩存的方法。三、緩存雪崩1.問(wèn)題描述數(shù)據(jù)庫(kù)壓力變大服務(wù)器崩潰在極少的時(shí)間段查詢(xún)大量的key的集中過(guò)期情況key對(duì)應(yīng)的數(shù)據(jù)存在但在redis中過(guò)期此時(shí)若有大量并發(fā)請(qǐng)求過(guò)來(lái)這些請(qǐng)求發(fā)現(xiàn)緩存過(guò)期一般都會(huì)從后端DB加載數(shù)據(jù)并回設(shè)到緩存這個(gè)時(shí)候大并發(fā)的請(qǐng)求可能會(huì)瞬間把后端DB壓垮。緩存雪崩與緩存擊穿的區(qū)別在于這里針對(duì)很多key緩存前者則是某一個(gè)key正常訪問(wèn)緩存失效瞬間2.解決方案緩存失效時(shí)的雪崩效應(yīng)對(duì)底層系統(tǒng)的沖擊非常可怕解決方案1 構(gòu)建多級(jí)緩存架構(gòu)nginx緩存 redis緩存 其他緩存ehcache等2 使用鎖或隊(duì)列用加鎖或者隊(duì)列的方式保證來(lái)保證不會(huì)有大量的線程對(duì)數(shù)據(jù)庫(kù)一次性進(jìn)行讀寫(xiě)從而避免失效時(shí)大量的并發(fā)請(qǐng)求落到底層存儲(chǔ)系統(tǒng)上。不適用高并發(fā)情況3 設(shè)置過(guò)期標(biāo)志更新緩存記錄緩存數(shù)據(jù)是否過(guò)期設(shè)置提前量如果過(guò)期會(huì)觸發(fā)通知另外的線程在后臺(tái)去更新實(shí)際key的緩存。4 將緩存失效時(shí)間分散開(kāi)比如我們可以在原有的失效時(shí)間基礎(chǔ)上增加一個(gè)隨機(jī)值比如1-5分鐘隨機(jī)這樣每一個(gè)緩存的過(guò)期時(shí)間的重復(fù)率就會(huì)降低就很難引發(fā)集體失效的事件。