一、设置key过期
EXPIREAT或PEXPIREAT命令
以秒或者毫秒精度为数据库中的某个键设置生存时间,当key过期,删除该key释放内存
二、Redis是如何判断一个键过期
redis中维护了一个expires字典,里面保存了数据库中所有设置了过期时间的键的过期时间,称为过期字典。
- 使用ttl(time to live)命令可以查询key的生存秒数
- 当前时间和过期时间比较,大于则过期
三、过期策略
定时删除
- 设置键的过期时间时,创建一个 Timer ,当到达指定过期时间,立刻删除键
- 内存友好型策略,一旦键过期,就会被删除,并释放所占用的内存,CPU 不友好,当一批数量比较多的键过期时,影响服务器对外的响应时间和和吞吐量
惰性删除
- 每次取键,判断一下该键是否过期,如果过期就删除
- CPU友好型,但是如果不是热点key,很长时间不访问,该key就算过期也会一直存在,造成内存泄漏
定期删除
- 由定时删除算法,定期的去检查一定的数据库,删除一定的过期键
- 通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用,CPU较为友好,但需要合理设置执行时长和频率,也会造成内存泄漏
- 定期删除可以通过:
- 配置redis.conf 的hz选项,默认为10 (即1秒执行10次,100ms一次,值越大说明刷新频率越快,最Redis性能损耗也越大)
- 配置redis.conf的maxmemory最大值,当已用内存超过maxmemory限定时,就会触发主动清理策略
Redis使用惰性删除 + 定期删除来删除过期key,合理设置可以让服务器可很好的在CPU的使用时间和避免浪费内存空间之间取得平衡。
四、淘汰策略
Redis 提供了配置参数 maxmemory 来限制内存超出期望大小,一旦达到该配置值,就会淘汰Redis的键值。
淘汰策略:
- volatile-lru :在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把 redis 既当缓存,又做持久化存储的时候才用
- allkeys-lru : 移除最近最少使用的key
- volatile-random : 在设置了过期时间的键空间中,随机移除一个键
- allkeys-random : 直接在键空间中随机移除一个键
- volatile-ttl : 在设置了过期时间的键空间中,有更早过期时间的key优先移除
- noeviction : 不做过键处理,只返回一个写操作错误
一般使用allkeys-lru策略
五、从库的过期策略
从库不会进行过期扫描,从库对过期的处理是被动的。主库在 key 到期时,会在 AOF 文件里增加一条 del 指令,同步到所有的从库,从库通过执行这条 del 指令来删除过期的 key。
redis版本在3.2以下,去从库读取过期key,不会使用惰性删除,在没有读主库的情况下,还是会读取到过期key的值,Redis3.2版本以上不存在该问题。所以在Redis做分布式锁的时候,最好使用ttl语句对读取的key做一次判断,确认key是否过期。