Redis内存策略

1.Redis中Key的过期策略

问题1:Redis是如何知道一个key是否过期呢?

        Redis会利用两个字典分别记录key-value对(dict)以及key-ttl对(expires)。

1.1 立即删除

        在设置键的过期时间时,会创建一个回调事件,当过期时间达到时, 自动执行回调事件去删除键。但是立即删除对 cpu 是最不友好的。

1.2 惰性删除

        惰性删除是指某个键值过期后,此键值不会马上被删除,而是等到下次访问该键值的时候,等到去expires中去查询才会发现过期了,此时才会删除。但是如果过期了,后面不在访问的话,就会一直在expires中,所以惰性删除的缺点就是会浪费内存

Redis内存策略_第1张图片

        由上面的两幅图我们发现其实在执行写操作和读操作时,都会先去expires字典中检查key是否过期。  

1.3 周期删除

通过一个定时任务,周期性的抽样部分的key,然后对过期的key执行删除。执行周期有两种:

1.Redis初始化时会设置一个定时任务serverCron(),按照server.hz的频率来执行过期key清理,模式为SLOW。

SLOW模式规则:

(1)执行频率受到server.hz的影响,默认为10,即每秒执行10次,每一个周期100ms。

(2)执行清理耗时不能超过一个周期时间的25%(即25ms)。

(3)逐个遍历,抽取20个key判断是否过期。

(4)如果没达到时间上限(25ms)并且过期key比列大于10%,则再进行一次抽样,否则结束。

2.Redis的每个事件循环前会调用beforeSleep()函数,执行过期key清理,模式为FAST。

FAST模式规则:

(1)与beforeSleep()(在注册FD监听前执行)调用频率有关,但是两次调用间隔不能低于2ms,如果低了,直接越过。

(2)执行清理耗时不超过1ms。

(3)逐个遍历,抽取20个key判断是否过期。

(4)如果没达到时间上限(1ms)并且过期key比列大于10%,则再进行一次抽样,否则结束。

1.4三种删除方式总结

可以看到,第二种为被动删除第一种和第三种为主动删除,且第三种实时性更高。每隔一段时间执行一次删除操作,并通过限制删除操作执行的时长和频率,来减少删除操作对 cpu 的影响。另一方面定时删除也有效的减少了因惰性删除带来的内存浪费。

所以redis使用的过期键值删除策略是:惰性删除加上定期删除,两者配合使用

2.淘汰策略

        内存淘汰:就是当Redis内存使用达到设置的阈值时,Redis主动挑选部分key删除以释放更多内存的流程。在配置文件中可以进行设置淘汰策略:

Redis内存策略_第2张图片

Redis支持8种不同策略来选择要删除的key,如下:

  • noeviction(默认):不淘汰任何key,但是内存满时不允许写入新数据。

  • volatile-TTL:对设置了TTL的key,比较key的剩余TTL值,TTL越小越先被淘汰。

  • allkeys-Random:对全体的key,随机进行淘汰。也就是直接从db->dict中随机挑选。

  • volatile-Random:对设置了TTL的key,随机进行淘汰。也就是从expires中随机挑选。

  • allkeys-LRU:对全体key,基于LRU算法进行淘汰。

  • volatile-LRU:对设置了TTL的key,基于LRU算法进行淘汰。

  • allkeys-LFU:对全体的key,基于LFU算法进行淘汰。

  • volatile-LFU:对设置了TTL的key,基于LFU算法进行淘汰。

    总体的流程如下:

Redis内存策略_第3张图片 

手写LRU算法:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

手写LFU算法:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

 

你可能感兴趣的:(Redis,redis,数据库,缓存)