緩存穿透是用戶訪問一個不存在的key,導致請求穿透到資料庫。 問題關鍵是程式上要識別出這個key是一個錯誤key,不是由系統生成的key。每次添加或刪除緩存時維護一個key欄位查詢過濾器,例如:布隆過濾器、HashSet。這樣在訪問緩存前,可以對key先進行查詢過濾,判斷key是否存在,再往下執行業 ...
緩存穿透是用戶訪問一個不存在的key,導致請求穿透到資料庫。 問題關鍵是程式上要識別出這個key是一個錯誤key,不是由系統生成的key。每次添加或刪除緩存時維護一個key欄位查詢過濾器,例如:布隆過濾器、HashSet。這樣在訪問緩存前,可以對key先進行查詢過濾,判斷key是否存在,再往下執行業務邏輯。 另一種辦法是把空結果緩存,key不存在有兩種情況,一是資料庫存在,但key緩存過期了,或者還沒把數據設置緩存,二是資料庫沒記錄,key不存在。要把這兩種情況區分開,程式才不會誤判。對於第二種,要把key緩存起來,值設置為空字元串返回,過期時間不宜設置太長,例如10分鐘內,因為資料庫雖然現在沒記錄,但將來可能有,設置一定有效期是有必要的,既能夠保持數據最終一致,又能解決穿透問題。第一種是資料庫存在,key不存在,返回的是null,繼續往下執行業務邏輯。 緩存雪崩是指大範圍key在同一時間失效,請求同一時間落到資料庫。 在每個key設置基礎失效時間上加上一個隨機失效時間,例如5分鐘內的隨機數,這樣就可以把失效時間分散開,避免集中在一個時間點上失效。 緩存擊穿是一個熱點key突然緩存時間到期失效,大量請求落到資料庫。 既然問題是熱點key緩存到期失效引起的,如果程式能在key臨近到期時,主動去更新緩存延期,就能避免被擊穿。在設置緩存時可以把到期時間記錄到緩存里,每次讀緩存時取出到期時間,判斷距離當前時間還有多久失效,假如已到達設定的閾值(如:1分鐘),則拉取最新數據更新緩存。建議根據您的業務執行時間去設置閾值,保證在閾值內能執行完緩存更新。 上篇文章說到用緩存雙刪來更新緩存,但在緩存刪掉後,讀業務沒了緩存層,在瞬間將面臨大流量擊穿到資料庫。假如熱點key設置了兩份緩存分別是C1和C2,並且C2過期時間要比C1長,當C1緩存不存在時,用C2緩存來緩衝。雖然像解決了問題,但C1被刪了,只能通過後臺作業或者消費隊列去更新C1,這樣做緩存雙刪就失去原來的作用了。所以不能光用緩存來檔流量,也要在原來緩存層上加入限流,把流量層層削弱,讓少部分流量留入資料庫,不至於宕機。下篇將講講如何限流