1. 程式人生 > 其它 >【10期】Redis 面試常見問答

【10期】Redis 面試常見問答

什麼是快取雪崩?怎麼解決?

快取雪崩是指快取中資料大批量到過期時間,而查詢資料量巨大,引起資料庫壓力過大甚至down機。和快取擊穿不同的是,快取擊穿指併發查同一條資料,快取雪崩是不同資料都過期或宕機了,很多資料都查不到從而查資料庫

如何解決呢?

  • 對快取做高可用,防止快取宕機。
  • 使用斷路器,如果快取宕機,為了防止系統全部宕機,限制部分流量進入 DB,保證部分可用,其餘的請求返回斷路器的預設值。
  • 快取資料的過期時間設定隨機,防止同一時間大量資料過期現象發生。
  • 如果快取資料庫是分散式部署,將熱點資料均勻分佈在不同搞得快取資料庫中。
  • 設定熱點資料永遠不過期。

什麼是快取穿透?怎麼解決?

快取穿透是指快取和資料庫中都沒有的資料,而使用者不斷髮起請求

,如發起為id為“-1”的資料或id為特別大不存在的資料。這時的使用者很可能是攻擊者,攻擊會導致資料庫壓力過大

如何解決呢?

  • 介面層增加校驗,如使用者鑑權校驗,id做基礎校驗,id<=0的直接攔截;
  • 從快取取不到的資料,在資料庫中也沒有取到,這時也可以將key-value對寫為key-null,快取有效時間可以設定短點,如30秒(設定太長會導致正常情況也沒法使用)。這樣可以防止攻擊使用者反覆用同一個id暴力攻擊。

什麼是快取擊穿?怎麼解決?

快取擊穿是指快取中沒有但資料庫中有的資料(一般是快取時間到期),這時由於併發使用者特別多,同時讀快取沒讀到資料,又同時去資料庫去取資料,引起資料庫壓力瞬間增大

,造成過大壓力。

如何解決呢

  • 設定熱點資料永遠不過期。
  • 可以在這些請求程式碼加上雙重檢查鎖。但是那個階段的請求會變慢。

什麼是快取併發競爭?怎麼解決?

多個客戶端寫一個 key,如果順序錯了,資料就不對了。但是順序我們無法控制。

如何解決呢

使用分散式鎖,例如 zk,同時加入資料的時間戳。同一時刻,只有搶到鎖的客戶端才能寫入,同時,寫入時,比較當前資料的時間戳和快取中資料的時間戳。

什麼是快取和資料庫雙寫不一致?怎麼解決?

連續寫資料庫和快取,但是操作期間,出現併發了,資料不一致了。

通常,更新快取和資料庫有以下幾種順序:

  • 先更新資料庫,再更新快取。

  • 先刪快取,再更新資料庫。

  • 先更新資料庫,再刪除快取。

先更新資料庫,再更新快取

這麼做的問題是:當有 2 個請求同時更新資料,那麼如果不使用分散式鎖,將無法控制最後快取的值到底是多少。也就是併發寫的時候有問題。

先刪快取,再更新資料庫

這麼做的問題:如果在刪除快取後,有客戶端讀資料,將可能讀到舊資料,並有可能設定到快取中,導致快取中的資料一直是老資料。

解決方案:延時雙刪策略,可將1秒內快取髒資料,再次刪除。最後一步的刪除通常是非同步操作,就是防止有客戶端讀取的時候設定了舊值。

先更新資料庫,再刪除快取

這個實際是常用的方案,但是有很多人不知道,這裡介紹一下,這個叫 Cache Aside Pattern,老外發明的。如果先更新資料庫,再刪除快取,那麼就會出現更新資料庫之前有瞬間資料不是很及時。

同時,如果在更新之前,快取剛好失效了,讀客戶端有可能讀到舊值,然後在寫客戶端刪除結束後再次設定了舊值,非常巧合的情況。

有 2 個前提條件:快取在寫之前的時候失效,同時,在寫客戶端刪除操作結束後,放置舊資料 —— 也就是讀比寫慢。甚至有的寫操作還會鎖表。

所以,這個很難出現,但是如果出現了怎麼辦?使用非同步延時雙刪!。

還有一種可能,如果執行更新資料庫,準備執行刪除快取時,服務掛了,執行刪除失敗怎麼辦???

簡單點的方法就是使用訊息佇列重試刪除:

更好的方案:通過訂閱資料庫的 binlog 來刪除