
緩存穿透、擊穿和雪崩別把三種問題混成一件事緩存能夠減少數據庫讀取也能讓高頻頁面更快返回。但緩存不是簡單加在數據庫前面就結束了。請求查不到數據、熱點剛好失效、大量鍵同時過期、緩存服務本身異常都會讓流量重新落到后端。若團隊把這些情況統稱為“緩存崩了”往往會套錯方案給不存在的數據加鎖給熱點一味延長過期時間或者只靠增加 Redis 容量來解決批量失效。更穩妥的做法是先區分現象再根據數據是否存在、熱點程度、過期分布和后端承受能力設計防護。緩存策略應服務于業務正確性和可用性不能為了提高命中率而返回不該返回的數據或把過期數據無限期留在系統里。穿透先判斷請求是否有意義緩存穿透通常指請求查詢的對象在緩存和數據源中都不存在。可能是用戶輸入錯誤、爬蟲探測、接口被濫用也可能是數據剛刪除后仍有舊鏈接被訪問。每次都直接查數據庫即使單次查詢很輕也會在高并發下形成持續壓力。處理前應確認“不存在”在業務上是什么意思。有些資源確實永遠不可能存在可以較早拒絕有些對象則可能剛創建、尚未同步過早判斷不存在會影響正常用戶。輸入參數校驗、權限校驗和業務狀態檢查應放在合適位置不能把所有未知標識一律當作攻擊。對可確認的無效請求可以使用短期的空結果緩存減少重復訪問下沉。過期時間需要根據數據創建和刪除的時效設計不能無限保存。布隆過濾器等概率結構也可以用于較大規模的已知集合它能可靠地排除某些不在集合中的鍵但“可能存在”并不代表數據庫一定有記錄后續仍要正常查詢和處理。擊穿關注的是單個熱點重建緩存擊穿與穿透不同它針對的是本來存在且訪問量很高的對象。當一個熱點鍵過期或失效時很多請求同時發現未命中并發回源加載同一份數據。后端壓力集中在一個對象的重建上常在活動頁、熱門內容或高頻配置讀取時出現。第一步是識別真正熱點而不是給所有鍵加復雜鎖。可以通過訪問量、重建成本和業務重要性判斷哪些對象需要特殊處理。普通鍵偶爾并發回源可能并不值得引入額外協調高熱點且重建昂貴的鍵才需要明確誰負責刷新、其他請求如何等待或降級。一種策略是在緩存失效后只允許有限請求觸發重建其他請求短暫等待、返回受控的舊值或給出可理解的稍后重試。鎖或單飛機制只能協調重建過程仍需要設置超時、失敗處理和持有者身份避免重建任務本身卡住時把所有請求長期阻塞。邏輯過期是另一種思路物理緩存保留數據業務根據記錄的更新時間決定它是否需要刷新。一個后臺任務更新數據其余請求在有限窗口內可以讀取舊值。這適合能夠接受短暫陳舊結果的場景例如內容展示或非實時配置對余額、庫存和強實時狀態則不應為了平滑而返回過期結果。雪崩看的是一批緩存同時失去作用緩存雪崩涉及的不是單個熱點而是一大批鍵在相近時間失效或緩存服務整體不可用。批量初始化時統一設置過期時間、定時任務集中刷新、發布時誤刪大范圍鍵都可能造成前者單點部署、網絡故障和容量耗盡則可能觸發后者。過期時間適度分散能夠降低同時回源的概率但它只是風險緩解不是絕對保證。隨機范圍要結合業務過期要求設計不能讓需要準時更新的內容被隨意拖延。更重要的是避免把大量關鍵鍵綁定到同一個刷新時刻并對批量操作設置范圍檢查和回滾路徑。緩存服務故障時后端需要有明確的保護策略。數據庫連接池、并發預算、限流和降級可以防止所有請求一起沖向數據源有些非關鍵功能可以暫時關閉或使用有限的本地結果。策略應區分接口優先級不能讓一項低價值查詢擠占核心交易所需資源。多副本、合理的客戶端超時和故障切換有助于提高緩存服務可用性但也要測試切換期間的行為。客戶端無限重試或同步等待可能在服務恢復前先把應用線程耗盡。緩存數據的正確性要有邊界緩存中保存什么、何時更新、刪除后怎樣失效都必須與數據寫入路徑協調。僅在讀取端添加緩存不處理寫入后的更新或失效會讓用戶長期看到舊數據。寫后刪除、更新緩存、事件驅動刷新等方式各有適用條件需要結合并發寫入和失敗恢復設計。不要把緩存當作權限判斷的最終來源。個性化數據、賬戶狀態和敏感信息需要按用戶與權限隔離緩存鍵或內容范圍不清楚時可能把一個用戶的結果返回給另一個用戶。命中率再高也無法彌補這種錯誤。觀測指標也應關注正確性命中與未命中、回源時間、重建失敗、空結果比例、過期數據讀取和緩存服務錯誤都能幫助判斷策略是否在按預期工作。只有 QPS 和內存使用量不足以說明緩存真的保護了后端。用真實失敗場景驗證策略上線前可以在受控環境模擬幾種關鍵情況持續請求不存在對象、熱點鍵同時過期、刷新任務失敗、大批鍵需要重新加載、緩存節點短暫不可用。觀察數據庫是否仍在可承受范圍內用戶是否得到適當反饋數據是否會錯誤地長期陳舊。發生異常后團隊應知道先保護什么、誰有權關閉某項緩存策略、如何恢復和核對數據。運行手冊不必寫得很長但應避免現場臨時執行大范圍刪除或無界重試。緩存穿透、擊穿和雪崩的共同點是都會增加回源壓力原因和處理方式卻不同。先識別對象是否存在、是否是熱點、是否會批量失效再選擇短期空值、受控重建、過期分散和后端保護緩存才能在壓力到來時真正發揮作用。