为什么要设定过期时间
- 内存是有限的,如果所有的对象都不设定过期时间,则很快Redis的内存就会不足。
- 在某些业务场景下需要使用到过期时间,例如验证码有效期等操作
Redis如何判断是否到达有效期
- Redis中维护了过期字典,存储在redisDb这个结构中。
- 过期字典的Key指向了redis的key
- value指向了该key所对应的过期时间,是毫秒级的时间戳
过期数据的删除策略
惰性删除
- 仅在用户查询时进行判断key所对应的过期时间是否达到,如果已经达到过期时间则返回空
定期删除
- 在过期字典内定期抽取20个key,进行过期时间的判断
- 查询出这20个key中已经过期的key,如果已经过期则进行删除。
- 如果已经过期的key超出查询key的1/4即5个,则会重复步骤1,继续抽取20个key判断是否删除
内存淘汰策略
为什么需要内存淘汰策略
- 即使已经存在过期时间的删除策略,包含惰性删除和定期删除,但是仍会有许多的情况下会导致内存满,当内存满的时候则需要进行内存淘汰。
Redis的内存淘汰策略
- volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰。
- volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰。
- volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰。
- allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)。
- allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰。
- no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!
- volatile-lfu(least frequently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最不经常使用的数据淘汰。
- allkeys-lfu(least frequently used):当内存不足以容纳新写入数据时,在键空间中,移除最不经常使用的 key。
从库的淘汰策略
- 在主库的key过期后,会向所有从库发送del指令
- 在读取从库时,如果key过期,会返回null