Redis的过期策略

Redis中缓存的数据是有过期时间的,当缓存数据失效时Redis会删除过期数据已节省内存,那Redis是怎么删除过期数据的?删除过期数据的策略是什么?Redis过期策略

Redis为什么这么快,原因之一是Redis的操作是基于内存的,既然基于内存的,而内存的大小是有限的,当内存不足或占用过高时,怎么办?Redis的内存淘汰机制

一、Redis过期策略

Redis在设置缓存数据时指定了过期时间,到了过期时间数据就失效了,那Redis是怎么处理这些失效的数据的呢?用到Redis的过期策略----“惰性删除+定期删除”。

1. 定期删除

定期删除是指Redis默认每隔100ms就随机抽取一些设置了过期时间的key,检测这些key是否过期,如果过期就将其删除。

  • 100ms怎么来的? 在Redis的配置文件redis.conf中有一个属性“hz”,默认设置为10,表示每1s执行10次定期删除,即每隔100ms执行一次,可以修改这个配置值。

  • 随机抽取一些检测,一些是多少? 同样是由redis.conf文件中的maxmemory-sample属性决定的,默认为5

  • 为什么随机抽取部分检测而不是全部? 因为如果Redis里面有大量的key都设置了过期时间,全部去检测一遍的话CPU负载会很高,会浪费大量时间在检测上面,甚至导致redis挂掉。所以只会抽取一部分而不会全部检测。 正因为定期删除只会随机抽取部分key来检测,这样的话就会出现大量已经过期的key并没有被删除,这就是为什么有时候大量的key明明已经过来失效时间,但是Redis的内存还是被大量占用的原因,为了解决这个问题,Redis又引入了“惰性删除策略”。

2. 惰性删除

惰性删除不是主动的去删除,而是在你要获取某个key的时候,redis会先去检测一下这个key是否已过期,如果没有则返回给你,如果已经过期,就将该key删除,并不返回给你。

“定期删除+惰性删除”就能保证过期的key最终一定能被删除,但是只能保障最终一定会被删除,要是定期删除遗漏的大量过期key,我们在很长的一段时间内也没有再访问这些key,那么这些过期key不就一直在内存中吗?不就一直占着内存吗?这样依然会导致Redis内存耗尽,由于存在这样的问题,所有Redis又引入了“内存淘汰机制”来解决。

二、Redis内存淘汰机制

内存淘汰机制能保证Redis内存占用过高的时候,去进行内存淘汰,也就是删除一部分key,保证redis的内存占用率不会过高,那么淘汰那些key?Redis目前提供了8种内存淘汰策略,含Redis 4.0版本之后又新增的两种LFU模式:volatile-lfu和allkeys-lfu

策略描述
no-eviction当内存不足以容纳新写入数据时,新写入操作会报错,无法写入数据,一般不采用
allkeys-lru当内存不足以容纳新写入数据时,移除最近最少使用的key,这个是最常用的
allkeys-random当内存不足以容纳新写入数据时,随机移除key
allkeys-lfu当内存不足以容纳新写入数据时,移除最不经常(最少)使用的key
volatile-lru当内存不足以容纳新写入数据时,在设置了过期时间的key中,移除最近最少使用的key
volatile-random当内存不足以容纳新写入数据时,在设置了过期时间的key中,随机移除key
volatile-lfu当内存不足以容纳新写入数据时,在设置了过期时间的key中,移除最不常用(最少)使用的key
volatile-tll当内存不足以容纳新写入数据时,在设置了过期时间的key中,优先移除过期时间最早(剩余存活时间最短)的key
  • 什么时候会执行内存淘汰策略,内存占用率高的标准是什么? redis.conf配置文件中的maxmemory属性限定了Redis最大内存使用量,当占用内存大于maxmemory的配置值时会执行内存淘汰策略,默认68%。

  • 内存淘汰策略的配置 内存淘汰策略由redis.conf配置文件中的maxmememory-policy属性设置,没有配置时默认是no-eviction模式。

  • 内存淘汰的执行过程 客户端执行一条命令,导致Redis需要增加数据(比如 set key value); Redis会检测内存使用情况,如果内存使用超过maxmemory,就会按照配置的过期策略maxmemory-polic删除一些key; 再执行新的数据的set操作;

三、其他场景对过期key的处理

  1. 快照生成RDB文件时 过期的key不会保存在RDB中。

  2. 服务重启载入RDB文件时 Master载入RDB时,文件中的未过期的键会被正常载入,过期键则会被忽略。Slave载入RDB时,文件中的所有键都会被载入,当主从同步时,再和Master保持一致。

  3. AOF文件写入时 因为AOF保存的是执行过的Redis命令,如果Redis还没有执行del,AOF文件中也不会保存del操作,当过期key被删除时,del命令也会被同步到AOF文件中去。

  4. 重写AOF文件时 执行BGREWRITEAOF时,过期的key不会被记录到AOF文件中。

  5. 主从同步时 Master删除过期key之后,会向所有Slave服务器发送一个DEL命令,Slave收到通知之后,会删除这些key。 Slave在读取过期键时,不会判断删除操作,而是继续返回该键对应的值,只有当Master发送DEL通知,Slave才会删除过期key,这是统一、中心化的键删除策略,保证主从服务器的数据一致性。