Redis緩存穿透,緩存擊穿,緩存雪崩緣由與解決方案

Redis緩存穿透,緩存擊穿,緩存雪崩緣由與解決方案

1. Redis緩存穿透,緩存擊穿,緩存雪崩

緩存穿透:key對應的數據在數據源並不存在,每次針對此key的請求從緩存獲取不到,請求都會到數據源,從而可能壓垮數據源。好比用一個不存在的用戶id獲取用戶信息,不論緩存仍是數據庫都沒有,若黑客利用此漏洞進行攻擊可能壓垮數據庫。redis

緩存擊穿:key對應的數據存在,但在redis中過時,此時如有大量併發請求過來,這些請求發現緩存過時通常都會從後端DB加載數據並回設到緩存,這個時候大併發的請求可能會瞬間把後端DB壓垮。數據庫

緩存雪崩:當緩存服務器重啓或者大量緩存集中在某一個時間段失效,這樣在失效的時候,也會給後端系統(好比DB)帶來很大壓力。後端

2. 解決方案

1. 緩存穿透

一個必定不存在緩存及查詢不到的數據,因爲緩存是不命中時被動寫的,而且出於容錯考慮,若是從存儲層查不到數據則不寫入緩存,這將致使這個不存在的數據每次請求都要到存儲層去查詢,失去了緩存的意義。緩存

有不少種方法能夠有效地解決緩存穿透問題最多見的則是採用布隆過濾器,將全部可能存在的數據哈希到一個足夠大的bitmap中,一個必定不存在的數據會被 這個bitmap攔截掉,從而避免了對底層存儲系統的查詢壓力。服務器

另外也有一個更爲簡單粗暴的方法(咱們採用的就是這種),若是一個查詢返回的數據爲空(無論是數據不存在,仍是系統故障),咱們仍然把這個空結果進行緩存,但它的過時時間會很短,最長不超過五分鐘。併發

2. 緩存擊穿

key可能會在某些時間點被超高併發地訪問,是一種很是「熱點」的數據。這個時候,須要考慮一個問題:緩存被「擊穿」的問題。高併發

業界比較經常使用的作法,是使用互斥鎖。簡單地來講,就是在緩存失效的時候(判斷拿出來的值爲空),不是當即去load db,而是先使用緩存工具的某些帶成功操做返回值的操做(好比Redis的SETNX或者Memcache的ADD)去set一個mutex key,當操做返回成功時,再進行load db的操做並回設緩存;不然,就重試整個get緩存的方法。工具

3. 緩存雪崩

有一個簡單方案就時將緩存失效時間分散開,好比咱們能夠在原有的失效時間基礎上增長一個隨機值,好比1-5分鐘隨機,這樣每個緩存的過時時間的重複率就會下降,就很難引起集體失效的事件線程

緩存標記:記錄緩存數據是否過時,若是過時會觸發通知另外的線程在後臺去更新實際key的緩存隊列

關於緩存崩潰的解決方法,三種方案:使用鎖或隊列、設置過時標誌更新緩存、爲key設置不一樣的緩存失效時間,還有一種被稱爲「二級緩存」的解決方法。

相關文章
相關標籤/搜索