redis 淘汰 Key 的策略

355 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第26天,点击查看活动详情

明明没有多少功能使用缓存,却发现缓存服务的内存使用率暴涨。经过一番查找后,发现某些业务没有设置缓存,甚至有些缓存设置的缓存过期时间过长。

Redis 淘汰原理

Redis 一般只存放最新最热的有效数据。下面2种场景 redis 会将过期或不活跃的 key 删除,从而回收内存:

  • 当缓存 Key 过期后,redis 将会对 key 进行淘汰
  • 当 Redis 内存使用率超出阀值

过期缓存 key, Redis 会定期执行清理。通过轮询每个 DB 检查其 expire dict。随机抽取 20个样本,若其中过期的key 的数超过 5个 则从中删除,继续抽取样本,直到样本过期的 key 数小于 5个时,则说明当前清理完毕,继续轮询下一个 DB。

轮询时如果某个 DB 中的缓存数据太少低于 1% 则放弃抽样检查。若缓存数据过多导致轮询时间过长,所以在5.0版本Redis 采用了慢循环过期策略,默认 25ms ,回收时间超出 25ms 就停止,在 6.0版本中采用快循环策略,过期时间是1mas

以上是在定期执行 serverCron 时会进行过期key 的清理。当 Redis 在执行命令请求时也会进行缓存清除。会检查当前内存占用是否超过 maxmemory 的数值,如果超过,则按照设置的淘汰策略,进行删除淘汰 key 操作。

淘汰策略

Redis 提供了 8 种 maxmemory_policy 淘汰策略来应对内存超过阀值的情况

  • Redis 的默认策略,noeviction 策略,内存超过阀值后,只要有写操作都返回错误,但读请求正常处理。适用场景:数据量不大的业务场景,将关键数据存入 Redis 中,将 Redis 作为 DB 使用
  • volatile-lru 策略,它对带过期时间的 key 采用最近最少访问算法来淘汰。
  • volatile-lfu 策略,它对带过期时间的 key 采用最近最不经常使用的算法来淘汰。
  • volatile-ttl 策略,它是对带过期时间的 key 中选择最早要过期的 key 进行淘汰。
  • volatile-random 策略,它是对带过期时间的 key 中随机选择 key 进行淘汰。
  • allkey-lru 策略,它是对所有 key,而非仅仅带过期时间的 key,采用最近最久没有使用的算法来淘汰。
  • allkeys-lfu 策略,它也是针对所有 key 采用最近最不经常使用的算法来淘汰。