本篇文章主要介紹redis的緩存穿透秉颗、緩存擊穿及緩存雪崩造成的原因及解決方案
一、緩存穿透
概念:是指查詢一個數(shù)據(jù)庫一定不存在的數(shù)據(jù)
解釋:客戶端請求數(shù)據(jù)送矩,redis中沒有蚕甥,則去數(shù)據(jù)庫查詢發(fā)現(xiàn)也沒有,如果在用戶量大或者有人惡意請求則會一直穿過緩存去請求數(shù)據(jù)庫栋荸,對數(shù)據(jù)庫造成很大的壓力菇怀。
解決方式:
- 在接口層根據(jù)業(yè)務(wù)增加一些用戶鑒權(quán)校驗,非法參數(shù)請求校驗晌块,降低數(shù)據(jù)庫壓力爱沟,比如id小于0之類的
- 設(shè)置空值緩存,在緩存中取不到數(shù)據(jù)匆背,并且在數(shù)據(jù)庫中也取不到數(shù)據(jù)呼伸,也可以將key-value對寫為key-null,但是需要設(shè)置一定合理的緩存過期時間钝尸,防止正常情況無法使用
- 設(shè)置布隆過濾器括享,他的原理也很簡單就是利用高效的數(shù)據(jù)結(jié)構(gòu)和算法快速判斷出你這個Key是否在數(shù)據(jù)庫中存在,不存在你return就好了蝶怔,存在你就去查了DB刷新KV再return奶浦。
二兄墅、緩存擊穿
概念:對于一些設(shè)置了過期時間的key踢星,如果這些key可能會在某些時間點被超高并發(fā)地訪問,是一種非诚断蹋“熱點”的數(shù)據(jù)
解釋:緩存在某個時間點過期的時候沐悦,恰好在這個時間點對這個Key有大量的并發(fā)請求過來,這些請求發(fā)現(xiàn)緩存過期一般都會從后端DB加載數(shù)據(jù)并回設(shè)到緩存五督,這個時候大并發(fā)的請求可能會瞬間把后端DB壓垮藏否。
解決方式:
- 設(shè)置熱點數(shù)據(jù)永遠不過期。
- 加互斥鎖充包,如果緩存中有數(shù)據(jù)則查詢到直接返回副签,如果換成中不存在數(shù)據(jù)則加鎖讓獲取鎖的這個線程去讀取數(shù)據(jù),然后后續(xù)線程還是讀取緩存基矮。比如redis的setNx
- "提前"使用互斥鎖,在讀取時對比緩存時間如果快到了則進行加鎖淆储,更新時間及重新從數(shù)據(jù)庫拉去數(shù)據(jù)。
三家浇、緩存雪崩
概念:指緩存大量失效本砰,導致大量的請求都直接向數(shù)據(jù)庫獲取數(shù)據(jù),造成數(shù)據(jù)庫的壓力
解釋:緩存雪崩造成的原因可能是因為我們在設(shè)置緩存時大量緩存的過期時間設(shè)置的一致或緩存服務(wù)器宕機钢悲,導致同時過期点额,大量請求直接奔向數(shù)據(jù)庫
解決方式:
- 加鎖舔株,減低數(shù)據(jù)庫壓力,但是這樣的效率比較低
- 在設(shè)置redis過期時間時加上一個隨機數(shù)还棱,避免大批數(shù)據(jù)過期場景
- 部署分布式redis载慈,在一臺redis服務(wù)器故障時,立刻將請求轉(zhuǎn)移到另一臺