先看现象。缓存写入时报内存不足,应用侧读到大量空值,数据库压力瞬间升高,重启缓存能恢复一会儿。
真正麻烦的地方在于,几个原因的现象几乎一样。最大内存限制设得太小。还有一种是淘汰策略配置成了不淘汰,写满就拒绝。
另外,存在大 key,单个键占了几百兆。
动手时先看内存使用和淘汰策略
redis-cli info memory | grep -E 'used_memory_human|maxmemory_human'
接着确认策略配置
redis-cli config get maxmemory-policy
然后改成按最近最少使用淘汰
redis-cli config set maxmemory-policy allkeys-lru
等前面都确认过,再找出占用最大的键
redis-cli --bigkeys
这类问题以前遇到过,但这次的触发条件和上次不一样。
这类改动我都写进变更记录,过两周再出问题时能对上号。
改完先别撤,确认这几项。内存使用稳定在限制以内,缓存命中率恢复,写入不再被拒绝。
提醒一点。淘汰策略选错会误删重要键,做会话存储时要用带过期时间的策略;大 key 拆分比调大内存更有效。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。