redis缓存过期策略学习

转自:http://jinguoxing.github.io/redis/2018/10/10/redis-EXPIRE/

https://juejin.cn/post/7058918503255900167

1.过期字典

在redis中维护了一个expires字典,里面保存了数据库中所有设置了过期时间的键的过期时间,称为过期字典。 

判断key是否过期,也是通过过期字典来完成的:

    ①首先检查给定键是否存在于过期字典中,若存在则取得键的过期时间

    ②检查当前UNIX时间戳是否大于键的过期时间,如果是的话则键已过期,若否则未过期

过期键存储在 redisDb 结构中:https://cloud.tencent.com/developer/article/1684105

typedef struct redisDb {
    dict *dict;                 /* The keyspace for this DB */
    dict *expires;              /* Timeout of keys with a timeout set */
    ...
}

 过期字典的键是一个指向键空间中的某个键对象的指针,值保存了键所指向的过期时间。

2.删除策略

2.1 定时删除

在设置键的过期时间的同时,创建一个定时器,定时定时器在键的过期时间来临时,立即执行对键的删除操作。(主动删除策略)

  • 优点:定时删除策略对内存是友好的;通过使用定时器,定时删除策略可以保证过期键会尽快地被删除,并释放过期键所占用的内存 。

  • 缺点:它对CPU时间是最不友好的;在过期键比较多的情况下,删除过期键这一行为会占用相当一部分CPU时间,对服务器的响应时间和吞吐量造成影响。

2.2 惰性删除

放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除改键;如果没有过期,就返回该键。 (被动删除策略)

  • 优点: 惰性删除策略对CPU 时间来说是最友好的:程序只会在取出键时才对键进行过期检查,这可以保证删除过期键的操作只会在非做不可的情况下进行, 并且删除的目标仅限于当前处理的键,这个策略不会在删除其他无关的过期键上花费任何CPU时间。

  • 缺点:它对内存是最不友好的: 如果一个键已经过期,而这个键又仍然保留在数据库中,那么只要这个过期键不被删除,它所占用的内存就不会释放。有内存泄漏的危险。

2.3定期删除

每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。 (主动删除策略)是定时和惰性的折中。

  1. 从过期字典中随机取出 20 个键。
  2. 删除这 20 个键中过期的键。
  3. 如果过期 key 的比例超过 25%,重复步骤 1。

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

redis服务器实际使用的是惰性删除和定期删除两种策略:通过配合使用这两种删除策略,服务器可很好的使用CPU的时间和避免浪费内存空间之间取得平衡。

 还有缓存淘汰策略,这次先不看了。有机会再看。

 

posted @ 2023-03-05 21:26  lypbendlf  阅读(45)  评论(0编辑  收藏  举报