redis过期删除机制,内存回收机制(淘汰策略)
过期键的删除策略
《redis设计与实现》中提到三种过期键删除策略,redis采用惰性删除策略与定时删除策略:
序号 | 名称 | 说明 |
---|---|---|
1 | 定时删除策略 | 设置键的同时设置一个定时器 |
2 | 惰性删除策略 | 从键空间获取键时,如果过期则删除 |
3 | 定期删除策略 | 每隔一段时间删除部分过期键,只会扫描设置了过期时间的键 |
惰性删除时如何判断一个键已经过期
- 从expires字典表中,查询是否存在key键,不存在则无过期时间,存在则获取该key的过期时间
- 将该key过期时间戳与当前时间比较得出是否该key已经过期。(三种过期时间:lua时间、redis服务时间、系统时间,经过测试,一般为redis服务时间)
淘汰策略
- 什么是淘汰策略
淘汰策略即redis自动的选择性的删除一些键,那么为什么需要redis自动删除一些键呢?
假如 Redis 当中所有的键都没有过期,而且此时内存满了,那么客户端继续执行 set 等命令时 Redis 会怎么处理呢?Redis 当中提供了不同的淘汰策略来处理这种场景,实际上redis有个配置参数(maxmemory)可以设置redis的最大使用内存空间 配置redis可使用的内存空间
- 查看maxmemory的命令:
config get maxmemory
默认设置的maxmemory的值为0,那么在 32 位的操作系统中 Redis 最多使用 3GB 内存,而在 64 位的操作系统中则不作限制,随着key-value越来越多,Redis性能会急剧下降- 设置maxmemory为1GB的命令:
config set maxmemory 1GB
- 查看maxmemory的命令:
8种淘汰策略
Redis内存不足的缓存淘汰策略提供了8种,其中volatile前缀的策略都是从已设置过期时间数据集中进行淘汰,allkeys前缀的策略都是面向所有key进行淘汰。名称 说明 noeviction 当内存使用超过配置的时候会返回错误,不会驱逐任何键。 allkeys-lru 加入键的时候,如果过限,首先通过LRU算法驱逐最久没有使用的键。 volatile-lru 加入键的时候如果过限,首先从设置了过期时间的键集合中驱逐最久没有使用的键。 allkeys-random 加入键的时候如果过限,从所有key随机删除。 volatile-random 加入键的时候如果过限,从过期键的集合中随机驱逐。 volatile-ttl 从配置了过期时间的键中驱逐马上就要过期的键。 volatile-lfu 从所有配置了过期时间的键中驱逐使用频率最少的键。 allkeys-lfu 从所有键中驱逐使用频率最少的键。 这八种大体上可以分为4中,lru、lfu、random、ttl。
- lru:Least Recently Used,最近最少使用。
- lfu:Least Frequently Used,最不经常使用法。
- ttl:Time To Live,生存时间。
- random:随机。
- 修改淘汰策略的两种方式
- 内存淘汰策略我们可以通过配置文件来修改,redis.conf 对应的配置项是“maxmemory-policy noeviction”,只需要把它修改成我们需要设置的类型即可。如果使用修改 redis.conf 的方式,当设置完成之后需要重启 Redis 服务器才能生效。
- 另一种简单的修改内存淘汰策略的方式,我们可以使用命令行工具输入
config set maxmemory-policy noeviction
来修改内存淘汰的策略,这种修改方式的好处是执行成功之后就会生效,无需重启 Redis 服务器。但它的坏处是不能持久化内存淘汰策略,每次重启 Redis 服务器之后设置的内存淘汰策略就会丢失。