導讀
使用Redis難免會遇到Redis緩存穿透,緩存擊穿,緩存雪崩,熱點Key的問題。有些同學可能只是會用Redis來存取,基本都是用項目里封裝的工具類來操作。但是作為開發,我們使用Redis時可能會遇到上述問題,可能你還不知道這幾個名詞是什么意思,那么現在就讓我們一起來探討下吧。
首先我們使用Redis的邏輯是這樣的:
即:先從緩存取,緩存有就直接返回,沒有就查庫,查到就存Redis里,沒有返回空。
在實際使用Redis的時候一定會遇到緩存穿透、緩存擊穿、緩存雪崩和熱點key的問題,這幾個概念是什么?對應的怎么解決?一起來看下。
緩存穿透
是針對數據庫和緩存中都沒有的數據。場景:當客戶端發起查詢時,緩存中沒有就會去查庫,庫里也沒有,就會返回給客戶端錯誤信息。這樣是沒問題的,看起來邏輯是完美的,但是這里存在一個漏洞,那就是無論什么樣的Key過來查,我們都去接受它的請求,這就可能會被黑客抓住,發起大量請求,並且Key都是我們系統中沒有的,庫里也查不到對應的值,這樣的Key稱之為非法Key。那么當大量這樣的請求過來時是不是都不會命中Redis,然后都會打到DB上,當DB瞬時接收到如此多的連接時,DB就有可能撐不住,掛掉。這就是存在的一個隱藏的漏洞,黑客或者惡意攻擊者就會抓住這一點攻擊你的系統,使你的系統癱瘓。
實際開發中就要考慮到這一點,可以在系統層面加一層過濾,將系統認為非法的key進行一次攔截,直接返回給客戶端錯誤信息。具體這層過濾怎么加,哪些是非法Key要根據實際的業務邏輯來定,這里只給出解決思路。
緩存擊穿
是針對緩存中沒有但數據庫有的數據。場景是,當Key失效后,假如瞬間突然涌入大量的請求,來請求同一個Key,這些請求不會命中Redis,都會請求到DB,導致數據庫壓力過大,甚至扛不住,掛掉。
這個問題的解決辦法就是:
1、設置熱點Key,自動檢測熱點Key,將熱點Key的過期時間加大或者設置為永不過期,或者設置為邏輯上永不過期,具體設置方法待會說。
2、加互斥鎖。當發現沒有命中Redis,去查數據庫的時候,在執行更新緩存的操作上加鎖,誰拿到鎖誰去更新,同時在拿到鎖之后先從緩存再獲取一次如果有就返回,沒有就查庫然后更新。(雙重校驗)
緩存雪崩
是指大量Key同時失效,對這些Key的請求又會打到DB上,同樣會導致數據庫壓力過大甚至掛掉。
這個問題的解決辦法就是,讓Key的失效時間分散開,可以在統一的失效時間上再加一個隨機值,或者使用更高級的算法分散失效時間。
熱點Key問題
針對熱點數據,我們可以設置熱點Key的過期時間很大,或者在邏輯上永不過期。啥意思呢?
意思就是說,假如我們設置熱點數據過期時間為24小時,那么我們可以使用監聽器去監聽這熱點數據,當檢測到它快要過期時,異步起個線程去更新這個熱點數據。可以達到邏輯上永不過期的效果。
另外一點,我們要有熱點數據自動檢測機制。即有個監控平台,來監控每個key某個時間段的請求次數,過期次數,查庫次數,來分析這個key是不是熱點數據,當達到某閾值時將key升級為熱點key,然后走熱點數據的邏輯。
這里只提供思路,具體怎么實現不再贅述。如果有更好的辦法,歡迎留言交流。