具代表性的面試主題

後端面試:如何用 Redis HEXPIRE 設計雜湊欄位級 TTL?

後端中等
Offer.cc 編輯團隊發佈 更新

題幹

一個使用者雜湊同時保存短期推薦特徵和長期資料,兩個欄位需要不同 TTL。你會如何評估 HEXPIRE,而不是拆成大量 Redis key?

題幹與適用場景

系統希望在同一個 Redis hash 中保存多個欄位,但每個欄位的有效期不同。請說明如何使用 HEXPIRE、如何處理續期條件、讀取過期狀態、記憶體回收、舊版本相容和恢復。不要只寫命令語法。

面試官考察點

  • 是否理解 Redis 7.4 的過期粒度從 key 擴展到 hash field。
  • 是否能正確使用 NX、XX、GT、LT 條件並解釋回傳值。
  • 是否考慮過期刪除時機、讀寫競態、通知、持久化和記憶體預算。
  • 是否能設計版本探測、降級、監控和資料恢復方案。

回答前需要釐清的問題

  1. 欄位是否允許獨立過期,還是必須整體原子地更新多個欄位?
  2. TTL 是依業務事件計算,還是固定到期時間?重複寫入能否延長有效期?
  3. 過期後業務要回傳缺失、預設值,還是觸發重新計算?是否需要過期事件?
  4. Redis 版本、叢集模式、持久化方式和舊客戶端是否支援欄位級 TTL?

30 秒回答框架

我會先確認欄位獨立生命週期是否值得保留在同一個 hash 中,再為每個欄位定義 TTL、續期條件和缺失語義。HEXPIRE 可按欄位設定相對秒數,並用 NX、XX、GT、LT 防止無意縮短或延長期限;命令回傳值要納入監控。上線前驗證讀取、重寫、過期通知、故障恢復和舊版本降級,不能把欄位過期誤解為定時精確刪除。

分步驟深入解答

1. 建模欄位生命週期

為每個欄位定義資料來源、最大新鮮度、續期事件和過期後的替代值。需要整體原子更新的欄位仍可放在同一 hash,但 TTL 設定和業務寫入必須在一個可重試的協議中協調。

2. 選擇續期條件

首次設定可用 NX,只在已有過期時間時更新可用 XXGT 只接受更長 TTL,LT 只接受更短 TTL。對每個欄位記錄設定命令的回傳碼,區分欄位不存在、條件不滿足、成功更新和立即刪除。

3. 處理過期與通知

欄位過期不等於應用執行緒在精確時刻收到事件。讀取時必須接受欄位缺失,寫入時避免把舊快照重新寫回;需要驅動重算時,結合 keyspace notification 或業務佇列,並設計重複事件與遺失事件的補償。

4. 相容、監控與恢復

啟動時探測 Redis 版本和客戶端能力;不支援欄位 TTL 時可降級為獨立 key,但要明確記憶體和原子性變化。監控剩餘 TTL、條件失敗、過期事件、命中率和記憶體;從 RDB/AOF 恢復後重新核對關鍵欄位的有效期與重算任務。

高品質示範回答

我會先把每個欄位的生命週期、續期來源和過期後行為寫成協議,再判斷是否需要 hash 的共享讀取與原子更新。使用 HEXPIRE 設定欄位 TTL,首次寫入用 NX,只在已有 TTL 時更新用 XX,防止縮短或延長則分別考慮 GTLT,並記錄回傳值。讀取路徑把過期欄位視為缺失,不能依賴精確時刻的刪除通知;若要觸發重算,用通知加業務佇列和冪等補償。上線前探測版本、驗證故障恢復、監控 TTL/命中率/記憶體,並準備獨立 key 降級方案。

常見錯誤

  • HEXPIRE 當成整個 hash 的 EXPIRE 別名。
  • 不理解 NX、XX、GT、LT,重複寫入時無意修改 TTL。
  • 假設欄位會在指定秒數精確時刻被刪除並收到唯一事件。
  • 忽略舊版本、客戶端和叢集相容性。
  • 沒有定義欄位缺失、重算、重複通知和恢復語義。
  • 只看命中率,不監控 TTL、條件失敗和記憶體回收。

追問及應對

什麼時候仍應拆成多個 key?

當欄位必須跨服務獨立原子更新、客戶端不支援欄位 TTL,或過期與存取模式更適合整 key 時,拆 key 更簡單。要把額外 key 數量、記憶體開銷和一致性成本量化。

GT 為什麼適合推薦特徵?

推薦特徵通常只能在新鮮度更高時延長有效期;GT 可拒絕更短 TTL,避免晚到的舊事件把新資料提前過期。

如何處理過期通知遺失?

通知只做加速,不做唯一事實來源。讀取未命中、定期掃描剩餘 TTL、業務水位和冪等重算佇列應共同覆蓋遺失或重複事件。

公開來源

同類題目