快取的雷有一個共同的狡猾之處:當下全部都能動。 每查必快取?能動。TTL 不設?能動。把 Redis 當資料庫?能動好幾個月。爆的時候都在很後面,而且爆點跟病灶隔得很遠——DB 被打爆的時候,沒人會想到是三個月前那行「順手 cache 一下」。
所以這篇的每一條都用同一個結構講:它為什麼當下看起來沒事,以及它之後怎麼爆。
一、什麼都快取
新同事學會 CacheService 之後的第一個症狀:每個查詢都包一層快取,連一天被查一次的後台報表都不放過。
當下沒事,因為快取讀寫很快,感覺「反正不虧」。實際上虧在三處:沒人重複讀的資料,每次都是 miss +回填——純付出、零回收,每個請求還多一次網路來回;記憶體被一次性資料塞滿,把真正的熱資料擠去淘汰(傷到別人的命中率);每多一份快取,就多一處「資料改了要不要失效」的心智負擔。
判斷準則一句話:會被重複讀、而且可以忍受短暫落後的資料,才值得快取。 兩個條件缺一個,就直接查 DB。
二、TTL 訂無限大(或忘了訂)
「這資料很少變,不設過期沒關係吧。」當下沒事,因為資料真的很少變。
爆法有二:某天它終於變了,而你的失效邏輯剛好漏掉這個 key(總會漏的),這筆髒資料永遠不會自我修正——TTL 是一致性的最後保險絲,你把保險絲拔了;再者永生 key 只進不出,記憶體水位緩慢上漲,幾個月後撞上 maxmemory 開始淘汰,全站命中率莫名下滑,沒人查得到為什麼。
就算資料「幾乎不變」,也給一個長 TTL(一天、一週都行)。「幾乎不變」和「永遠不變」之間的差距,就是事故的棲息地。
三、把快取當真相來源
最危險的一條。Redis 又快又好用,用著用著就有資料只存在 Redis 裡——沒有 DB 備份的購物車、只寫進快取的計數、拿快取當唯一的 session 憑證做金流判斷。
當下沒事,因為 Redis 很穩。但 Redis 的持久化語意是「盡量不掉」不是「保證不掉」:極端情況下最後一小段寫入會消失;記憶體滿了淘汰策略還可能主動丟你的資料。把「掉了會出事」的東西放在一個「被設計成可以掉」的系統裡,時間問題而已。
紀律:每一份放進快取的資料,都要能回答「掉了怎麼辦」。 答不出來的,它的家在 DB,不在 Redis。
四、敏感資料裸放
把含個資的整包物件、token、甚至密碼相關資訊直接快取。當下沒事——快取在內網,誰看得到?
爆在:Redis 常常是全公司權限管最鬆的系統(多服務共用、沒有 ACL、開發機直連),任何一個能連上的人 SCAN 一下就把個資撈走;再加上除錯時 MONITOR、日誌、RedisInsight 都會把值原文展示——敏感資料的暴露面比你以為的大得多。
原則:快取裡只放「洩漏了不致命」的資料形態——要嘛去識別化、要嘛只存 id 由下游再查、真的要放就加密。以及,Redis 該有的 ACL 和網段隔離不是選配。
五、DB 跟快取之間沒有一致性策略
寫入的地方各寫各的:有的更新 DB 順便更新快取、有的只更新 DB、有的先刪快取再寫 DB。當下沒事,因為低併發下怎麼寫都對。
流量上來之後,各種交錯開始出現:舊值蓋新值、剛刪的快取被舊資料回填。而且這種髒是間歇性的——使用者回報「有時候看到舊資料,重整又好了」,你連重現都重現不了。
解法不用花俏,但要全隊一致:讀 cache-aside、寫「先改 DB 再刪快取」、一律短 TTL 收尾。把它寫進 CacheService 讓人沒辦法各寫各的,比寫進 wiki 有效十倍。
六、忽視 cold start
平常命中率 97%,一切美好。然後某次部署重啟了 Redis(或換了台新的)——快取是空的,那一瞬間 100% 的流量直灌 DB。你的 DB 容量是按「有快取的世界」規劃的,扛不住這個瞬間,於是雪崩、連鎖超時、全站掛掉。快取越成功的系統,這一刻摔得越重。
對策分兩層:預熱——重啟後先用腳本把最熱的 key 填回去再開流量;兜底——DB 前面永遠留著限流或斷路器,確保「快取整層消失」時系統是「變慢」而不是「死掉」。順帶一提,這也是「快取要不要持久化」的真正判斷點:RDB/AOF 對純快取的價值不是資料本身,是重啟後不用冷啟動。
[作者補:親眼看過或聽過的其中一種反模式事故]
六條收成一句:快取的所有反模式,本質都是忘了它的身分——它是加速器,是可以隨時消失的副本,不是真相、不是保險箱、也不是免費的。 每次伸手寫 cache.set 之前想一下這句,六個雷就避掉五個了。
(正確的讀寫姿勢見 #11、TTL 怎麼訂見 #14、監控怎麼上見 #25——這篇的每個反模式,都有對應的正面教材。)
接下來往哪走
- 設計 CacheService 抽象層 — 反模式的系統性解法:把紀律做進介面,讓錯的寫法寫不出來
- Cache Hit Rate 監控 — 反模式在爆之前,曲線上早有腳印
- 為什麼「加個 cache」常常讓事情更糟 — 反模式爆開之後的四種現場