引言
大家都知道Redis是内存数据库,将所有的数据都放在内存中,而内存经常会出现饱和的情况,为了节约内存空间,Redis会将过期数据清除,当内存满时会通过指定策略进行淘汰。本章讲解Redis过期数据删除策略与淘汰策略。
数据过期策略
设置过期时间
设置key过期时间有4个命令:
expire <key> <n>
:设置 key 在 n 秒后过期,比如 expire key 100 表示设置 key 在 100 秒后过期;pexpire <key> <n>
:设置 key 在 n 毫秒后过期,比如 pexpire key2 100000 表示设置 key2 在 100000 毫秒(100 秒)后过期。expireat <key> <n>
:设置 key 在某个时间戳(精确到秒)之后过期,比如 expireat key3 1655654400 表示 key3 在时间戳 1655654400 后过期(精确到秒);pexpireat <key> <n>
:设置 key 在某个时间戳(精确到毫秒)之后过期,比如 pexpireat key4 1655654400000 表示 key4 在时间戳 1655654400000 后过期(精确到毫秒)- 在设置字符串时,也可以同时对 key 设置过期时间,共有 3 种命令:
set <key> <value> ex <n>
:设置键值对的时候,同时指定过期时间(精确到秒);set <key> <value> px <n>
:设置键值对的时候,同时指定过期时间(精确到毫秒);setex <key> <n> <valule>
:设置键值对的时候,同时指定过期时间(精确到秒)。查看key的剩余时间:使用TTL <key>命令。
取消key的过期时间,使用PERSIST <key>命令。
过期删除策略
当key过期,Redis会先把该key协同过期时间存储到一个过期字典EXPIRES DICT中。
随后根据特定的过期删除策略进行删除,常见的过期删除策略分为三种:定时删除、惰性删除、定期删除。
定时删除
- 创建定时器,当过期时间到达,定时器立即执行删除。
- 优点:节省内存
- 缺点:在设置的过期时间段中占用CPU用于过期检查,增加CPU的负载。
惰性删除
- 设置key过期时间中,我们不用去管它,当需要该key是,我们在检查是否过期,如果过期,删除key,不过期返回key值。
- 优点:对CPU友好,只会在使用该key的时候进行检查,对于很多用不到的key不用浪费时间进行过期检查。
- 对内存不友好,一直不使用过期的key,该key会一直占用内存。
定期删除
- 每个一段时间,我们就对一些key进行检查,删除里面的过期key,随机取出定量的key进行检查。
- 优点:可以通过限制删除操作执行的时长和频率来检查哦操作对CPU的影响,同时也能删除一部分过期的数据减少了过期键对空间的无效占用。节省内存。
- 缺点:难以确定删除操作执行的时长和频率。
分为两种模式
SLOW模式:是定时任务,执行频率默认为10HZ,每次不超过25ms,通过修改conf文件的HZ来修改次数。
FAST模式:执行频率不固定,但两次间隔不低于2ms,每次耗时不超过1ms。
默认过期删除策略
以上的过期删除策略各有优缺点,Redis默认的过期删除策略是惰性删除+定期删除两种策略进行配合使用。
内存淘汰策略
当Redis 的运行内存已经超过 Redis 设置的最大内存之后,则会使用内存淘汰策略删除符合条件的 key,以此来保障 Redis 高效的运行。
LRU与LFU算法
LRU:Least Recently Used 最近最少使用。用当前时间减去最后一次访问时间,值越大则淘汰优先级越高。
LFU:Least Frequently Used 最少频率使用。通过统计每个key的访问频率值越小淘汰优先级越高。
淘汰策略
- noeviction:不淘汰key,当内存满使不允许写入数据。默认策略
- volatile-random:随机淘汰设置了过期时间的任意键值;
- volatile-ttl:对设置TTL的key,比较剩余的TTL值,值越小越先淘汰。
- volatile-lru:在所有设置了过期时间的键值中,对最久未使用的键值进行淘汰。
- volatile-lfu:在所有设置了过期时间的键值中,对最少使用的键值进行淘汰。
- allkeys-random:随机淘汰任意键值;
- allkeys-lru:在整个键值中对最久未使用的键值进行淘汰;
- allkeys-lfu:在整个键值中对最少使用的键值进行淘汰。
淘汰策略使用建议
- 在业务有明显的热冷数据的区分,使用allkeys-lru策略,可以用来区分冷热数据的区分。
- 没有明显的热冷数据区分使用allkeys-random。