幾種現象很常見,基本都是在高併發的場景下,因爲大量請求沒有在緩存中查詢到數據而從數據庫中查詢,形成了數據庫的併發量瞬間增大。數據庫
好比2000的QPS,對於Redis來講頂的很輕鬆,可是普通服務器上的數據庫就很難頂。緩存
下面對這集中狀況進行一個簡單介紹,並總結一些解決方案。服務器
項目中,一般會將熱點數據保存到Redis並設置過時時間,好比在12點將熱點數據放到Redis中,過時時間爲1小時。併發
請求時,先去Redis讀取數據,若是Redis中不存在該數據,就去數據庫中讀取數據,而後放到緩存中。高併發
這種設計在併發大時會出現一個問題。spa
如上面的設計,在1點、2點、3點……的時候,若是緩存失效時,系統併發請求過大,就會對數據庫形成周期性的壓力。設計
其實緩存的集中過時並非很是致命的,最致命的雪崩狀況是緩存服務器失效(死機、斷網)。基礎
之因此這麼說,是由於緩存集中過時形成的緩存雪崩,也會集中建立緩存,數據庫興許能夠頂住。配置
但由於緩存服務節點失效而形成的緩存雪崩,對數據庫形成的壓力則是難以預估的,頗有可能把數據庫壓垮,形成系統不可用。請求
這種狀況下,若是緩存由於過時時間到達而失效,那麼就會有大量的請求打到數據庫,形成周期性的數據庫壓力。
總結:緩存忽然不可能,接着來的大量請求瞬間打在了數據庫。
一、隨機設置緩存的過時時間:在指定的緩存過時時間上,隨機在加上必定時間的過時,不讓緩存在同一時間過時,好比超時時間是固定的5分鐘,能夠隨機加上2分鐘內的秒數。
二、緩存備份,在A緩存節點設置過時時間,B緩存節點不設置過時時間,當A失效時去讀取B。
三、不設置過時時間,在修改數據庫時更新緩存。
緩存穿透是指,在緩存和數據庫中都沒有的數據,而用戶不斷髮起請求,形成數據庫壓力增大。
例如,數據庫中的數據主鍵使用自增,從1開始。可是用戶不斷查詢主鍵爲「-1」的數據,或主鍵特別大的不存在的數據。這時的用戶極可能是攻擊者,攻擊會致使數據庫壓力過大。
一、在應用程序層增長校驗,如用戶鑑權校驗,主鍵基礎校驗等。
二、應用程序作限流、熔斷、降級,能夠從網關層進行限流(例如在Nginx中進行配置),或者使用相似Hystrix的組件進行熔斷或降級。
三、使用布隆過濾器,先判斷要查詢的主鍵是否存在。
四、使用互斥鎖。
緩存擊穿是指緩存中沒有,但數據庫中有的數據。
例如,緩存中保存了一個很是熱的數據,當緩存過時的同時,併發讀取這個熱數據的用戶特別多,同一時間讀緩存但沒讀到數據,又同時去數據庫去取數據,形成了數據庫的壓力瞬間增大,這種狀況就叫緩存擊穿。
一、設置熱點數據永遠不過時,更新數據庫的同時更新緩存。
二、使用互斥鎖;