Redis过期策略

Redis 所有的数据结构都可以设置过期时间,时间一到,就会自动删除。你可以想象
Redis 内部有一个死神,时刻盯着所有设置了过期时间的key,寿命一到就会立即收割。

因为 Redis 是单线程的,收割的时间也会占用线程的处理时间,如果收割的太
过于繁忙,会不会导致线上读写指令出现卡顿。

1. 过期删除

redis 会将每个设置了过期时间的key放入到一个独立的字典中,以后会定时遍历这个字典来删除到期的 key。

1.1 定时扫描策略

Redis 默认会每秒进行十次过期扫描,过期扫描不会遍历过期字典中所有的key,而是采用了一种简单的贪心策略。

  • 从过期字典中随机20个key
  • 删除这20个key中已经过期的key
  • 如果过期的key比率超过 1/4,那就重复步骤 1

同时,为了保证过期扫描不会出现循环过度,导致线程卡死现象,算法还增加了扫描时间的上限,默认不会超过 25ms。

1.2 从库的过期策略

从库不会进行过期扫描,从库对过期的处理是被动的。主库在 key 到期时,会在 AOF 文件里增加一条 del 指令,同步到所有的从库,从库通过执行这条 del 指令来删除过期的key。

因为指令同步是异步进行的,所以主库过期的 key 的del指令没有及时同步到从库的
话,会出现主从数据的不一致,主库没有的数据在从库里还存在。

2. 懒惰删除

一直以来我们认为 Redis是单线程的,单线程为Redis带来了代码的简洁性和丰富多样的数据结构。不过 Redis内部实际上并不是只有一个主线程,它还有几个异步线程专门用来处理一些耗时的操作。

2.1 unlink指令

删除指令 del 会直接释放对象的内存,大部分情况下,这个指令非常快,没有明显延迟。不过如果删除的 key 是一个非常大的对象,比如一个包含了千万元素的 hash,那么删除操作就会导致单线程卡顿。

Redis 为了解决这个卡顿问题,在4.0版本引入了unlink指令,它能对删除操作进行懒处理,丢给后台线程来异步回收内存。

2.2 flush async指令

Redis 提供了 flushdb和flushall指令,用来清空数据库,这也是极其缓慢的操作。
Redis 4.0 同样给这两个指令也带来了异步化,在指令后面增加async参数就可以将整棵大树连根拔起,扔给后台线程慢慢焚烧。

3. 内存淘汰策略

如果定期删除和懒惰删除之后,还有数据没清理完的话,Redis提供了内存淘汰机制。

当 Redis 内存超出物理内存限制时,内存的数据会开始和磁盘产生频繁的交换 (swap)。交换会让 Redis 的性能急剧下降,对于访问量比较频繁的 Redis 来说,这样龟速的存取效率基本上等于不可用。

在生产环境中我们是不允许 Redis 出现交换行为的,为了限制最大使用内存,Redis 提供了配置参数 maxmemory 来限制内存超出期望大小。

当实际内存超出 maxmemory 时,Redis 提供了几种可选策略 (maxmemory-policy) 来让用户自己决定该如何腾出新的空间以继续提供读写服务。

官网提供了以下几种内存淘汰策略:

  • noeviction 不会继续服务写请求(DEL请求可以继续服务),读请求可以继续进行。这样可以保证不会丢失数据,但是会让线上的业务不能持续进行。这是默认的淘汰策略。
  • volatile-lru 尝试淘汰设置了过期时间的key,最少使用的key优先被淘汰。没有设置过期时间的 key 不会被淘汰,这样可以保证需要持久化的数据不会突然丢失。
  • volatile-ttl 跟上面一样,除了淘汰的策略不是 LRU,而是 key 的剩余寿命 ttl 的值,ttl 越小越优先被淘汰。
  • volatile-random 跟上面一样,不过淘汰的 key 是过期 key 集合中随机的 key。
  • allkeys-lru 区别于 volatile-lru,这个策略要淘汰的 key 对象是全体的 key 集合,而不只是过期的 key 集合。这意味着没有设置过期时间的 key 也会被淘汰。
  • allkeys-random 跟上面一样,不过淘汰的策略是随机的 key。
  • volatile-xxx 策略只会针对带过期时间的 key 进行淘汰,allkeys-xxx 策略会对所有的key 进行淘汰。如果你只是拿 Redis 做缓存,那应该使用 allkeys-xxx,客户端写缓存时不必携带过期时间。如果你还想同时使用 Redis 的持久化功能,那就使用 volatile-xxx 策略,这样可以保留没有设置过期时间的 key,它们是永久的 key 不会被 LRU 算法淘汰。

参考资料

  1. 《Redis深度历险》

你可能感兴趣的:(Redis过期策略)