深入学习 Redis 原理 - 过期策略

Introduction

主要分类:

  1. 定时过期
  2. 惰性过期
  3. 定期过期

Redis 采用的是惰性过期 + 定期过期的策略,而 Memcached 采用惰性过期。

Redis 惰性过期流程:

  1. 在进行get或setnx等操作时,先检查key是否过期;
  2. 若过期,删除key,然后执行相应操作;若没过期,直接执行相应操作

Redis 定期过期流程:

  1. 遍历每个数据库(就是redis.conf中配置的”database”数量,默认为16);
  2. 检查当前库中的指定个数个key(默认是每个库检查20个key,注意相当于该循环执行20次,循环体时下边的描述);
    1. 如果当前库中没有一个key设置了过期时间,直接执行下一个库的遍历;
    2. 随机获取一个设置了过期时间的key,检查该key是否过期,如果过期,删除key;
    3. 判断定期删除操作是否已经达到指定时长,若已经达到,直接退出定期删除。

RDB 对过期 key 的处理:

  1. 从内存数据库持久化数据到RDB文件,持久化key之前,会检查是否过期,过期的key不进入RDB文件。
  2. 从RDB文件恢复数据到内存数据库,会对key先进行过期检查,如果过期,不导入数据库(主库情况)。

AOF 对过期key的处理:

  1. 从内存数据库持久化数据到AOF文件:

    1. 当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令);
    2. 当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉);
  2. AOF重写:重写时,会先判断key是否过期,已过期的key不会重写到aof文件。

定时过期

在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除。

Advantage:

  • 保证内存被尽快释放;

Weakness:

  • 若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key;
  • 定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重;

惰性过期

key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。

Advantage:

  • 删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了)

Weakness:

  • 若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)

定期过期

每隔一段时间执行一次删除(在redis.conf配置文件设置hz,1s刷新的频率)过期key操作。

Advantage:

  • 通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用 - 避免了”定时过期”和”惰性过期”的缺点。

Weakness:

  • 在内存友好方面,不如”定时删除”;
  • 在CPU时间友好方面,不如”惰性删除”;

注意:合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除),这个要根据服务器运行情况来定了。


Reference