緩存雪崩redis
緩存雪崩,是指在某一個時間段,緩存集中過時失效。數據庫
產生雪崩的緣由之一,好比在寫本文的時候,立刻就要到雙十二零點,很快就會迎來一波搶購,這波商品時間比較集中的放入了緩存,假設緩存一個小時。那麼到了凌晨一點鐘的時候,這批商品的緩存就都過時了。而對這批商品的訪問查詢,都落到了數據庫上,對於數據庫而言,就會產生週期性的壓力波峯。緩存
解決思路:服務器
第一,大多數考慮用加鎖或者隊列的方式保證來保證不會有大量的線程對數據庫一次性進行讀寫,避免緩存失效時對數據庫形成太大的壓力,雖然可以在必定的程度上緩解了數據庫的壓力可是與此同時又下降了系統的吞吐量。併發
第二,分析用戶的行爲,儘可能讓緩存失效的時間均勻分佈。分佈式
第三,若是是由於某臺緩存服務器宕機,能夠考慮作主備,好比:redis主備,可是雙緩存涉及到更新事務的問題,update可能讀到髒數據,須要好好解決。高併發
其實集中過時,倒不是很是致命,比較致命的緩存雪崩,是緩存服務器某個節點宕機或斷網。由於天然造成的緩存雪崩,必定是在某個時間段集中建立緩存,那麼那個時候數據庫能頂住壓力,這個時候,數據庫也是能夠頂住壓力的。無非就是對數據庫產生週期性的壓力而已。可是緩存服務節點的宕機,對數據庫服務器形成的壓力是不可預知的,頗有可能瞬間就把數據庫壓垮。spa
緩存失效的時候以下圖:線程
兩種實際方法:blog
1. 併發量不是特別多的時候,使用最多的解決方案是加鎖排隊。
加鎖排隊只是爲了減輕數據庫的壓力,並無提升系統吞吐量。假設在高併發下,緩存重建期間key是鎖着的,這是過來1000個請求999個都在阻塞的。一樣會致使用戶等待超時,這是個治標不治本的方法!
注意:加鎖排隊的解決方式分佈式環境的併發問題,有可能還要解決分佈式鎖的問題;線程還會被阻塞,用戶體驗不好!所以,在真正的高併發場景下不多使用!
2.還有一個解決辦法解決方案是:給每個緩存數據增長相應的緩存標記,記錄緩存的是否失效,若是緩存標記失效,則更新數據緩存。
解釋說明:
緩存標記:記錄緩存數據是否過時,若是過時會觸發通知另外的線程在後臺去更新實際key的緩存;
緩存數據:它的過時時間比緩存標記的時間延長1倍,例:標記緩存時間30分鐘,數據緩存設置爲60分鐘。 這樣,當緩存標記key過時後,實際緩存還能把舊數據返回給調用端,直到另外的線程在後臺更新完成後,纔會返回新緩存。
3. 好比作電商項目的時候,通常是採起不一樣分類商品,緩存不一樣週期。在同一分類中的商品,加上一個隨機因子。這樣能儘量分散緩存過時時間,並且,熱門類目的商品緩存時間長一些,冷門類目的商品緩存時間短一些,也能節省緩存服務的資源。
關於緩存崩潰的解決方法,這裏提出了三種方案:使用鎖或隊列、設置過時標誌更新緩存、爲key設置不一樣的緩存失效時間,還有一各被稱爲「二級緩存」的解決方法,有興趣的讀者能夠自行研究。