赞
踩
1. Redis中设置Key过期时间
我们有两种方式设置过期时间
1.1 设置多久后过期
设置一个 key 10s 过期,可以这样
127.0.0.1:6379> SET key value EX 10
127.0.0.1:6379> SET key value PX 10000
PX 后面是毫秒ms,EX是秒。
设置完成后,10s内,可以查询到,我们也可以使用 ttl 命令查看多长时间后过期。
127.0.0.1:6379> TTL key
(integer) 8
等到过了10s后,再查询,发现就查询不到了。
1.2 设置在什么时候过期
127.0.0.1:6379> EXPIREAT key 1577808000
其中 1577808000 是 2020-01-01 00:00:00 对应的时间戳。
没过期的时候,我们也可以使用 EXPIRE 命令直接将key设置成过期。
也可以使用 PERSIST 将 key 设置为永久不过期。
那么当时间到的时候, key 在 redis 中是怎么过期的呢?如何清理呢?
2. 惰性删除
redis 中,一个key过期,并不会马上清除,而是惰性删除。
即当下次读取这个 key 时会进行检查,如果发现已经过期了,会返回空,并且立即删除掉它。
当一个key被scan的时候发现已经过期了,也会被删除。
3. 定期删除
上面提到的惰性删除有一个问题,那就是,如果一个key已经过期了,但永远不会被读取到,它就会一直在内存中,浪费内存空间。
为了解决这个问题,redis又在“惰性删除”的基础上加了“定期删除”机制。
redis会随机读取一些key进行检查,如果发现它们过期了,就会立即删除它们。当然,实际的实现要比这复杂,但这是主要思想。
Redis Server运行时,会运行着定期清除事件,在 Redis 2.6 版本中,一分钟触发10次,平均每 100ms 运行一次。从 Redis 2.8开始, 用户可以通过修改 hz选项来调整每秒执行次数,具体信息可以修改 redis.conf 文件中 hz 选项。
定期删除,这里的“定期”指的是Redis定期触发的清理策略,由位于src/redis.c的activeExpireCycle(void)函数来完成。
key过期相关源代码链接:https://github.com/antirez/redis/blob/a92921da135e38eedd89138e15fe9fd1ffdd9b48/src/expire.c#L98
3. 当 redis 存储满了,会怎么样?
通过上述两种手段结合起来,大部分过期的key会被删掉。
但也会有一些过期key,没有被“定期删除”扫描到,也没有被访问到,堆积在内存里,导致redis内存耗尽了,怎么办?
Redis定义了几种策略,即“内存淘汰机制”,来处理这种情况:
VolatileLRU 按照LRU算法逐出原有数据,但仅逐出设置了过期时间的数据(常用)
VolatileTTL 仅逐出设置了过期时间的数据,并且是按照TTL从小到大的顺序进行逐出
VolatileRandom 随机逐出原有数据,但仅逐出设置了过期时间的数据
AllKeysLRU 按照LRU算法逐出原有数据
AllKeysRandom 随机逐出原有数据
NoEviction 不逐出任何数据,新数据的写入会得到一个错误信息
不知道LRU算法的同学可以看看这个 LRU算法简介。
LFU的核心思想是按照key最近被访问的频率进行淘汰。
需要注意的是,如果使用 Volatile开头的几种策略,如果没有可以淘汰的key时,会像 NoEviction 一样,报错,无法写入。
最后总结
Redis key过期的方式有三种:
惰性删除:当读/写一个已经过期的key时,会触发惰性删除策略,直接删除掉这个过期key(无法保证冷数据被及时删掉)
定期删除:Redis会定期主动淘汰一批已过期的key(随机抽取一批key检查)
内存淘汰机制:当前已用内存超过maxmemory限定时,触发主动清理策略。
一句话:惰性删除 + 定期删除 + 内存淘汰机制
思考题:
在memcache中不给key设置过期时间,意味着key“永久不过期”,这个key就不会被删除么?
答案:不是,memcache不是持久化的,不设置过期时间意味着key不会主动被删除,但由于内存不足,server重启等各种原因,key还是可能被删除。
创作不易,有收获记得分享哦。关注微信,提升自己
万水千山总是情,点个 “在看” 行不行!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。