前言
本文已收录到 Github-java3c ,里面有我的系列文章,欢迎大家Star。
Hello 大家好,我是l拉不拉米
,这篇文章是我的『超级架构师』专栏系列文章,欢迎大家关注该专栏。
内存淘汰策略
Maxmemory配置
maxmemory
配置指令用于配置Redis存储数据时指定限制的内存大小。通过redis.conf
可以设置该指令,或者之后使用CONFIG SET
命令来进行运行时配置。
例如为了配置内存限制为100mb,以下的指令可以放在redis.conf
文件中。
maxmemory 100mb
设置maxmemory
为0
代表没有内存限制。对于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
做的事情:
- 测试随机的
20
个keys进行相关过期检测。 - 删除所有已经过期的keys。
- 如果有多于
25%
的keys过期,重复步奏1。
不断重复过期检测,直到过期的keys的百分百低于25%,在任何给定的时刻,最多会清除1/4的过期keys。
最后
创作不易,感谢您的点赞!!🙏🙏