Redis 面試常見問答

1. 什麼是緩存雪崩?怎麼解決?

一般,咱們會使用緩存用於緩衝對 DB 的衝擊,若是緩存宕機,全部請求將直接打在 DB,形成 DB 宕機——從而致使整個系統宕機。html

如何解決呢?面試

2 種策略(同時使用):shell

  1. 對緩存作高可用,防止緩存宕機
  2. 使用斷路器,若是緩存宕機,爲了防止系統所有宕機,限制部分流量進入 DB,保證部分可用,其他的請求返回斷路器的默認值。

2. 什麼是緩存穿透?怎麼解決?

解釋 1:緩存查詢一個沒有的 key,同時數據庫也沒有,若是黑客大量的使用這種方式,那麼就會致使 DB 宕機。數據庫

解決方案:咱們可使用一個默認值來防止,例如,當訪問一個不存在的 key,而後再去訪問數據庫,仍是沒有,那麼就在緩存裏放一個佔位符,下次來的時候,檢查這個佔位符,若是發生時佔位符,就不去數據庫查詢了,防止 DB 宕機。緩存

解釋 2: 大量請求查詢一個剛剛失效的 key,致使 DB 壓力倍增,可能致使宕機,但實際上,查詢的都是相同的數據。架構

解決方案:能夠在這些請求代碼加上雙重檢查鎖。可是那個階段的請求會變慢。不過總比 DB 宕機好。併發

3. 什麼是緩存併發競爭?怎麼解決?

解釋:多個客戶端寫一個 key,若是順序錯了,數據就不對了。可是順序咱們沒法控制。異步

解決方案:使用分佈式鎖,例如 zk,同時加入數據的時間戳。同一時刻,只有搶到鎖的客戶端才能寫入,同時,寫入時,比較當前數據的時間戳和緩存中數據的時間戳。分佈式

4.什麼是緩存和數據庫雙寫不一致?怎麼解決?

解釋:連續寫數據庫和緩存,可是操做期間,出現併發了,數據不一致了。 一般,更新緩存和數據庫有如下幾種順序:ide

  1. 先更新數據庫,再更新緩存。
  2. 先刪緩存,再更新數據庫。
  3. 先更新數據庫,再刪除緩存。

三種方式的優劣來看一下:

  1. 先更新數據庫,再更新緩存。 這麼作的問題是:當有 2 個請求同時更新數據,那麼若是不使用分佈式鎖,將沒法控制最後緩存的值究竟是多少。也就是併發寫的時候有問題。

  2. 先刪緩存,再更新數據庫。 這麼作的問題:若是在刪除緩存後,有客戶端讀數據,將可能讀到舊數據,並有可能設置到緩存中,致使緩存中的數據一直是老數據。 有 2 種解決方案:1. 使用「雙刪」,即刪更刪,最後一步的刪除做爲異步操做,就是防止有客戶端讀取的時候設置了舊值。2. 使用隊列,當這個 key 不存在時,將其放入隊列,串行執行,必須等到更新數據庫完畢才能讀取數據。

總的來說,比較麻煩。

  1. 先更新數據庫,再刪除緩存 這個實際是經常使用的方案,可是有不少人不知道,這裏介紹一下,這個叫 Cache Aside Pattern,老外發明的。若是先更新數據庫,再刪除緩存,那麼就會出現更新數據庫以前有瞬間數據不是很及時。 同時,若是在更新以前,緩存恰好失效了,讀客戶端有可能讀到舊值,而後在寫客戶端刪除結束後再次設置了舊值,很是巧合的狀況。 有 2 個前提條件:緩存在寫以前的時候失效,同時,在寫客戶度刪除操做結束後,放置舊數據 —— 也就是讀比寫慢。設置有的寫操做還會鎖表。 因此,這個很難出現,可是若是出現了怎麼辦?使用雙刪!!!記錄更新期間有沒有客戶端讀數據庫,若是有,在更新完數據庫以後,執行延遲刪除。

還有一種可能,若是執行更新數據庫,準備執行刪除緩存時,服務掛了,執行刪除失敗怎麼辦??? 這就坑了!!! 不過能夠經過訂閱數據庫的 binlog 來刪除。

參考

緩存更新的套路 原創 分佈式之數據庫和緩存雙寫一致性方案解析 Cache-Aside pattern

歡迎工做一到五年的 Java 的工程師朋友們加入的 Java 架構開發:685-167-672

本羣提供免費的學習指導架構資料以及免費的解答

不懂得問題均可以在本羣提出來以後還會有職業生涯規劃以及面試指導  

相關文章
相關標籤/搜索