Redis-key过期处理策略

前言

关于redis处理过期key首先想到几个问题如下:

  1. Redis如何自己回收清理不用的数据,存在什么样的策略?
  2. 是否可通过配置来控制?
  3. 如果不能自己回收清理,有是如何防止数据累加后大量占用存储空间? 很久之前学习redis时注意到redis对key过期处理,有几种策略,但是未曾记住,今天来总结下,算是温故知新吧。

如何设置key的过期时间

Redis对存储值的过期处理实际上是针对该值的键(key)处理的,即时间的设置也是设置key的有效时间。Expires字典保存了所有键的过期时间,Expires也被称为过期字段。

主要有以下几种方式:

  • EXPIRE key seconds (以秒为单位)
  • EXPIREAT key timestamp (unix 时间戳) 在timestamp时过期
  • PEXPIRE key milliseconds 设置 key 的过期时间以毫秒计。
  • PEXPIREAT key milliseconds-timestamp 设置 key 过期时间的时间戳(unix timestamp) 以毫秒计

返回值: 一个整数值1或0,如下:

如果成功地为该键设置了超时时间,返回 1
如果键不存在或无法设置超时时间,返回 0

如果没有设置时间,那缓存就是永不过期

过期策略

  • 定时删除
    • 含义:在设置key的过期时间的同时,为该key创建一个定时器,让定时器在key的过期时间来临时,对key进行删除
    • 优点:保证内存被尽快释放
    • 缺点:若过期key很多,删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下,CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key
      定时器的创建耗时,若为每一个设置过期时间的key创建一个定时器(将会有大量的定时器产生),性能影响严重
  • 惰性删除
    • 含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期,若过期,则删除,返回null。
    • 优点:删除操作只发生在从数据库取出key的时候发生,而且只删除当前key,所以对CPU时间的占用是比较少的,而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已经过期的key了)
    • 缺点:若大量的key在超出超时时间后,很久一段时间内,都没有被获取过,那么可能发生内存泄露(无用的垃圾占用了大量的内存)
  • 定期删除
    • 含义:每隔一段时间执行一次删除(在redis.conf配置文件设置hz,1s刷新的频率)过期key操作
    • 优点:通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用–处理”定时删除”的缺点; 定期删除过期key–处理”惰性删除”的缺点
      *缺点:在内存友好方面,不如”定时删除”;在CPU时间友好方面,不如”惰性删除”
  • 定时删除和定期删除为主动删除:Redis会定期主动淘汰一批已过去的key
  • 惰性删除为被动删除:用到的时候才会去检验key是不是已过期,过期就删除
    惰性删除为redis服务器内置策略

  • 定期删除可以通过:

    1. 配置redis.conf 的hz选项,默认为10 (即1秒执行10次,100ms一次,值越大说明刷新频率越快,最Redis性能损耗也越大)
    2. 配置redis.conf的maxmemory最大值,当已用内存超过maxmemory限定时,就会触发主动清理策略

memcached只是用了惰性删除,而Redis同时使用了惰性删除与定期删除

不同持久化操作对过期key的处理

  • RDB
    1. 从内存数据库持久化数据到RDB文件
      • 持久化key之前,会检查是否过期,过期的key不进入RDB文件
    2. 从RDB文件恢复数据到内存数据库
      • 数据载入数据库之前,会对key先进行过期检查,如果过期,不导入数据库(主库情况)
  • AOF
    1. 从内存数据库持久化数据到AOF文件:
      • 当key过期后,还没有被删除,此时进行执行持久化操作(该key是不会进入aof文件的,因为没有发生修改命令)
      • 当key过期后,在发生删除操作时,程序会向aof文件追加一条del命令(在将来的以aof文件恢复数据的时候该过期的键就会被删掉)
    2. AOF重写
      • 重写时,会先判断key是否过期,已过期的key不会重写到aof文件

参考

  1. [redis 官方文档] (https://redis.io/commands/expire)
  2. Redis 设计与实现 黄健宏
坚持原创技术分享,您的支持将鼓励我继续创作!