线上缓存报警,内存打满,写入开始报错。翻配置,淘汰策略写的是 allkeys-lru。这个值决定了内存不够时先删谁。

拆开看名字。allkeys 指所有键都在候选范围里,lru 是最近最少使用。合起来:内存到上限时,在全部键里挑最久没被访问的那个删掉。

它跟 volatile 系列差在哪

volatile 系列只在设了过期时间的键里挑,没设过期时间的键永远安全。好处是关键数据不会被删,坏处是内存可能一直降不下来,因为可删的键太少。

allkeys 系列不看过期时间,所有键都可能被删。好处是内存一定能压住,代价是可能把关键的配置缓存清掉。

什么场景适合 allkeys-lru

  • 缓存内容能重建,删了下次访问再查数据库;
  • 访问有明显热点,少数键承担大部分请求;
  • 过期时间不统一,或者干脆没设。

典型的是页面片段缓存、商品详情缓存。这类数据丢了就是一次回源,用户基本感知不到。

什么时候别用

如果同一个实例里混着队列、会话、分布式锁这类不能随便丢的数据,allkeys 系列就很危险。内存一紧,正在排队的任务键被删掉,业务逻辑直接断,而且很难查。

这种时候要么拆实例,缓存归缓存,队列单独放;要么改成只淘汰过期键的策略,并给所有缓存键都设上过期时间。别嫌麻烦,混用的代价更大。

几个容易忽略的细节

LRU 在实现上是近似算法,随机采样一批键,从里面挑最久没用的,不是全局精确排序。所以偶尔删掉一个刚用过的键,也算正常。

另外,全量扫描类的命令会刷新键的访问时间,把冷数据刷热,影响淘汰判断。定时任务遍历所有键的时候,留意一下这个副作用。

还有,淘汰是被动的。内存没到上限时它不动作,所以别指望它帮你清理长期不用的旧数据。

该看什么指标

设上限、改策略只是止血。真正要看的是命中率曲线。命中率长期低于七成,说明缓存设计本身有问题,换策略解决不了,得回头看键的粒度、过期时间和预热的时机。

还有一点常被搞混:淘汰策略是兜底手段,不是容量规划。内存上限给到物理内存的一半左右,留出余量给系统和其他进程,比反复调整策略有效得多。上层业务真的需要全量保活,那该做的是加内存或者分片,而不是在淘汰规则上做文章。

上线前把策略、上限和监控一起定好,比出事之后再临时改配置稳妥。改配置虽然不用重启,但策略一换,原本靠过期时间清理的键会突然进入候选范围,命中率会抖一阵,这点心里要有数。