「Redis 好像變慢了。」
這句話在群組裡出現的時候,最常見的下一句是「要不要重啟看看」。先不要。Redis 跟大部分的系統一樣,出事時它其實把證據都留好了,你只是要知道去哪裡翻。這篇不是工具型錄,是照「你會依序摸到的順序」走一遍。
[作者補:一次「以為 Redis 慢、結果是 XX」的真實排查經驗]
第一站:SLOWLOG——誰在拖慢整台?
Redis 是單執行緒,一次做一件事。所以「Redis 變慢」十之八九不是它整體變慢,而是某個慢指令卡住了所有人——一個 KEYS *、一個對幾十萬成員的 set 做 SMEMBERS,執行期間其他所有連線都在排隊。
SLOWLOG GET 10 直接把最近最慢的指令攤給你看:哪個指令、帶什麼參數、花了幾微秒、誰下的。第一現場就是它。
redis-cli SLOWLOG GET 10看到 KEYS、SMEMBERS、HGETALL 配上大 key、LRANGE 0 -1——恭喜,抓到了。這類 O(N) 指令在資料量大的時候就是整台 Redis 的路障,解法不是調 Redis,是改 code(逐批的 SCAN 家族、限範圍讀取)。
第二站:INFO——健康檢查的儀表板
INFO 會吐一大串,真正要先看的就幾個:
used_memory/maxmemory——記憶體用到哪了。逼近上限的行為取決於淘汰策略:可能開始踢 key,也可能開始拒絕寫入。evicted_keys——被淘汰踢掉的 key 數。這個數字在漲,代表記憶體已經滿了、Redis 正在丟東西;如果被踢的是你以為會一直在的資料,很多「資料怎麼不見了」的靈異事件就是這裡來的。keyspace_hits/keyspace_misses——命中率。hits 除以兩者之和,長期低於九成的快取要嘛 TTL 訂太短、要嘛根本在快取沒人重複讀的東西。connected_clients——連線數異常暴增,通常是應用端連線洩漏或重試風暴。
redis-cli --stat 則是把幾個關鍵值變成每秒刷新的即時儀表,觀察「現在正在發生什麼」很好用。
第三站:MEMORY USAGE——找出吃記憶體的大戶
記憶體高居不下,下一個問題是「誰吃的」。MEMORY USAGE <key> 回報單一 key 實際佔的 bytes。配合 SCAN 抽樣掃一輪,大 key 無所遁形——常見兇手是「一直往裡塞、從來不清」的 list 或 set,以及「把整張表塞進一個 hash」的設計。
大 key 不只吃記憶體:讀它慢(回到 SLOWLOG 那站)、刪它也慢——刪大 key 用 UNLINK 不要用 DEL,前者把記憶體回收丟到背景做,不卡住別人。
MONITOR——最強大也最危險的一個
MONITOR 即時印出 Redis 收到的每一條指令。想知道「這個框架背後到底對 Redis 做了什麼」,開著 MONITOR 跑一次操作,所有指令原形畢露——拿來學習和抓「誰在打奇怪的指令」都是神器。
但注意兩件事:它有實際成本(Redis 要把每條指令複製一份給你,高流量下開著它整體吞吐會明顯掉),以及指令參數會原文顯示(裡面可能有敏感資料)。生產環境要用,短開短關。
兩個補位:GUI 跟長期監控
RedisInsight(官方 GUI):瀏覽 key、看型別和 TTL、跑指令,臨時排查比赤手 redis-cli 舒服。它列 key 用的是 SCAN 逐批——這也順便示範了正道,畢竟你不會希望你的 GUI 對生產環境下 KEYS *。
redis_exporter + Prometheus/Grafana:上面講的都是「出事後去看」,長期趨勢(命中率緩慢下滑、記憶體每週多 5%)要靠 metrics 拉出來畫圖,異常提前告警。快取命中率的監控值得單獨一篇,這裡先記著:沒有監控的快取,等於不知道自己有沒有在發揮作用。
最後一種:Redis 沒辦法告訴你的事
有一類事故,client 端只看得到「連線斷了」,真正的原因只寫在 server log:被 OS 的 OOM killer 幹掉(記憶體沒設上限、把主機吃垮)、持久化寫入失敗(磁碟滿了)。排查連線類問題時,別只盯著應用端的錯誤訊息,docker logs(或系統的 journal)翻一下 Redis 自己怎麼說——很多懸案翻開 server log 十秒破案。
收個尾。這一整篇其實就一句話:先拿證據,再下結論。 慢 → SLOWLOG;記憶體 → INFO 和 MEMORY USAGE;行為詭異 → MONITOR 短開一下;連線離奇斷 → server log。每一步都比「重啟看看」快,而且重啟只會把證據洗掉。
(哪些指令天生就慢、為什麼單執行緒一個卡全部卡,見同系列前面的效能篇;命中率監控展開見 #25。)
接下來往哪走
- Cache Hit Rate 監控 — 排查是出事後的事,這篇讓你在出事前就看到曲線不對
- Redis 資料結構 — SLOWLOG 抓到的 O(N) 指令,多半是結構用錯的罰款
- 快取反模式 — 工具抓得到症狀,病根通常在這六條裡