『超级架构师』Redis内存淘汰策略和过期键清除策略

281 阅读4分钟

前言

本文已收录到 Github-java3c ,里面有我的系列文章,欢迎大家Star。

Hello 大家好,我是l拉不拉米,这篇文章是我的『超级架构师』专栏系列文章,欢迎大家关注该专栏。

内存淘汰策略

Maxmemory配置

maxmemory配置指令用于配置Redis存储数据时指定限制的内存大小。通过redis.conf可以设置该指令,或者之后使用CONFIG SET命令来进行运行时配置。

例如为了配置内存限制为100mb,以下的指令可以放在redis.conf文件中。

maxmemory 100mb

设置maxmemory0代表没有内存限制。对于64位的系统这是个默认值,对于32位的系统默认内存限制为3GB。

当指定的内存限制大小达到时,需要选择不同的行为,也就是策略。 Redis可以仅仅对命令返回错误,这将使得内存被使用得更多,或者回收一些旧的数据来使得添加数据时可以避免内存限制。

淘汰策略

当maxmemory限制达到的时候,Redis会使用的行为由 Redis的maxmemory-policy配置指令来进行配置。

策略描述
volatile-lru从已设置过期时间的数据集中挑选最近最少使用的数据淘汰
volatile-ttl从已设置过期时间的数据集中挑选将要过期的数据淘汰
volatile-random从已设置过期时间的数据集中随机选择数据淘汰
allkeys-lru从所有数据集中挑选最近最少使用的数据淘汰
allkeys-random从所有数据集中随机选择数据进行淘汰
noeviction禁止驱逐数据(返回错误)
volatile-lfu(Redis 4.0引入)从已设置过期时间的数据集中通过统计访问频率,将访问频率最少的键值对淘汰
allkeys-lfu(Redis 4.0引入)从所有数据集中通过统计访问频率,将访问频率最少的键值对淘汰

过期键清除策略

过期时间设置

通过expire命令给已存在的key添加过期时间:

EXPIRE key seconds

或者在设置key的时候同步设置:以String类型为例

 SETEX mykey 60 redis

查看key的过期时间:

TTL KEY_NAME

过期时间移除

在超时之前,如果该key被修改,与之关联的超时将被移除。

  • persist key 持久化该key,超时时间移除。

  • set key newvalue 设置新值,会清除过期时间。

  • del key 会清除key和过期时间。

  • 例外情况:

    • lpush, zset, incr等操作,在高版本(2.1.3++)之后不会清除过期时间,毕竟修改的不是key本身。
    • rename 也不会清除过期时间,只是改key名字。

清除策略

  • 定时删除

    • 原理:在设置键的过期时间的同时,创建一个定时器(timer),让定时器在键的过期时间来临时,立即执行对键的删除操作。
    • 优点:能够很及时的删除过期的Key,能够最大限度的节约内存。
    • 缺点:对CPU时间不友好,如果过期的Key比较多时,可能会占用相当一部分CPU时间,对服务器的响应时间和吞吐量造成影响。
  • 惰性删除

    • 原理:在取出键时才对键进行过期检查,如果发现过期了就会被删除。
    • 优点:对CPU友好,能够最大限度的节约CPU时间。
    • 缺点:对内存不友好,过期的Key会占用内存,造成浪费。
  • 定期删除

    • 原理:定期删除策略是定时删除策略和惰性删除策略的一个折中。定期删除策略每隔一段时间执行一次删除过期键的操作,并通过限制删除操作执行的时长频率来减少删除操作对CPU时间的影响。
    • 优点:对CPU时间和内存空间的一种权衡,可以根据实际使用情况来调整删除操作执行的时长频率。
    • 缺点:确定删除操作执行的时长频率很难。如果删除操作执行的太频繁,或者执行的时间太长,退化成定时删除策略;如果删除操作执行的太少,或者执行时间太短,退化成惰性删除策略。

Redis采用后两种结合的方式

  • 读写一个key时,触发惰性删除策略。
  • 惰性删除策略不能及时处理冷数据,因此redis会定期主动淘汰一批已过期的key。
  • 内存超过maxmemory时,触发主动清理(内存淘汰策略)。

具体就是Redis每100ms做的事情:

  1. 测试随机的20个keys进行相关过期检测。
  2. 删除所有已经过期的keys。
  3. 如果有多于25%的keys过期,重复步奏1。

不断重复过期检测,直到过期的keys的百分百低于25%,在任何给定的时刻,最多会清除1/4的过期keys。

最后

创作不易,感谢您的点赞!!🙏🙏