Redis server went away
查看系統記錄檔時發現每天定時有該錯誤拋出:
PHP Fatal error:
Uncaught exception 'RedisException' with message 'Redis server went away'
拋出該問題的指令碼為統計指令碼,需要讀取前一天資料併入庫,最初以為是REDIS讀取太頻繁造成的,但將資料導到測試機後執行指令碼發現不會出現該情況,仔細調試發現手動執行時有一行代碼沒有執行,若執行該行則十分緩慢。該行代碼為:
$Redis->delete($Redis->keys($pre_key_del.'*'));
查看手冊有相應提示:
KEYS 的速度非常快,但在一個大的資料庫中使用它仍然可能造成效能問題,如果你需要從一個資料集
中尋找特定的 key ,你最好還是用 Redis 的集合結構(set)來代替。
登入redis通過info查看,記憶體使用量25G多,而KEY也有1.44億了。。。REIDS中有大量無用而又未設定到期時間的KEY存在。設定個到期時間,舉手之勞的事,還是有必要的。
used_memory_human:24.72G
db0:keys=144856453,expires=25357
通過測試機執行 keys prefix* 導致REDIS卡死,其他串連也連不上。所以定位到問題出現在keys命令上,也正如手冊上說的造成效能問題。
如何刪除未用到的KEY?
大部分KEY是有規律的,有特定首碼,需要拿到特定首碼的KEY然後刪除,網上有這樣的命令:
redis-cli -a redis-pwd -n 0 keys "preffix*" | xargs redis-cli -p 6379 -a redis-pwd -n 0 del
測試機執行keys "preffix-1*"時間大概40多s,這意味著redis要停40s+,而首碼是按天設定的,這樣子需要操作多次,因為業務的原因,不允許這麼操作,分分鐘都是錢~
最後想到的辦法是先從測試機上把滿足條件的key導到文本,前面的語句通過cat文本去拿。如:
redis-cli -p 6380 -a redis-pwd keys "preffix-1*" > /home/keys_redis/preffix-1
然後通過這些資料刪掉生產環境上的key。
cat /home/keys_redis/preffix-1 | xargs redis-cli -a redis-pwd -n 0 del
刪除的速度非常快,記憶體耗的也挺快,感覺像是有多少耗多少的。執行之後KEY的數量減少了95%+,記憶體也從25G降到了2G。不過有一個指數升高了 ———— mem_fragmentation_ratio,前後的memory對比:
# Memory 處理前used_memory:26839186032used_memory_human:25.00Gused_memory_rss:23518339072used_memory_peak:26963439000used_memory_peak_human:25.11Gused_memory_lua:31744mem_fragmentation_ratio:0.88mem_allocator:jemalloc-3.2.0# Memory 處理後used_memory:2399386704used_memory_human:2.23Gused_memory_rss:4621533184used_memory_peak:26963439000used_memory_peak_human:25.11Gused_memory_lua:31744mem_fragmentation_ratio:1.93mem_allocator:jemalloc-3.2.0
mem_fragmentation_ratio的問題可能還需要最佳化下,從redis這個問題可以看到,設定cache的時候我們也需要考慮到cache的維護問題,是否該設定cache的到期時間,key的命名方式如何管理,不能只想著把資料塞進去就萬事大吉了。