大家好,欢迎来到IT知识分享网。
Redis之内存淘汰机制
我们知道Redis运行在内存中,那这是不是意味着Redis可以使用全部的内存资源呢?这个需要取决用户有没有在redis.conf文件中配置maxmemory最大容量限制,如果没有配置那么Redis会一直向系统申请内存资源,这显然是不合理的,所以一般建议在使用Redis时一定需要给Redis设置最大容量,在设置最大容量后,Redis将不能一直向内存中存储资源,那么在内存达到maxmemory配置后Redis采用什么机制保证自身正常运行呢?这就要聊到Redis的内存淘汰策略。
Redis存在哪些淘汰策略
Redis中在4.0之前主要是6大淘汰策略,4.0之后又加了两种淘汰策略,总共是8种淘汰策略,除了一种不会淘汰数据的noeviction外其余7种可以按照淘汰范围进行划分,如下
上面的淘汰策略中比较难理解的应该是LRU算法和LFU算法,以典型的LRU为例。
通用LRU算法
LRU全名为Least Recently Used,从全名我们就可以知道它的具体作用就是按照最近使用最少的算法来过滤数据,将最近使用最为频繁的数据选出,相当于保留热点数据,那具体如何实现呢?
LRU用的就是一个简单的数据链表,链表头MRU,链表尾LRU,最近访问的数据会集中在MRU端,使用最不频繁的将越靠近LRU端,如下所示
LRU算法其实很简单,就是认为最近访问的数据最有可能还会被Redis再次访问,所以将最近访问的数据放入MRU端,不常用的数据将后移到LRU端,当开始淘汰内存数据时就将LRU端的数据淘汰,也就是最近访问最不频繁的。
但这种上面这种算法显然是有问题的,当在Redis中插入大量数据,那是不是有可能将链表里面的数据都替换呢?而且用LRU算法还需要缓存一个最近访问的数据链表,当有数据访问时还会有数据移动带来的内存开销,数据访问越多带来的数据移动开销也会越大,这样将会降低Redis的性能,所以Redis没有直接采用LRU算法,而是将LRU算法进行简化。
Redis中的LRU算法
之前在Redis的数据结构中提到了RedisObject对象,这个对象中包含元数据和指针pr,而这个元数据中就包含了lru、引用次数、数据类型、数据编码(raw编码embstr编码),如下所示
Redis中的LRU算法就是基于RedisObject中的元数据lru值为参考,在Redis淘汰数据时,会随机选择N个数据,把这些数据作为候选数据,Redis会从这些候选数据中选取出lru字段最小的数据淘汰,这个参数N其实就是一个淘汰的样本数也成为候选集,我们可以在Redis.conf文件中配置maxmemory-samples 5。
当Redis还需要淘汰元素时会以候选样本集合作为参考,选取比样本集合最小lru还小的lru数据放入集合中,然后淘汰集合中lru最小的数据。
这里可能有人好奇,我已经比较出了比样本集合中的lru还小的数据,为什么不直接淘汰而是还需要放入样本集合中呢?这个原因其实是加入集合的元素可能不止一个只有当候选集中的数据达到配置的样本数maxmemory-samples后才会淘汰数据,而淘汰数据也不是只淘汰一个,Redis会根据超过内存最大值maxmemory的情况来决定淘汰的数据量。
这样做的目的其实是利用了历史数据,减少比较量,将全局比较变为局部比较,这也是算法优化的一部分。
LFU算法
LFU算法是4.0版本提出,就是对LRU算法进行一些优化,LFU需要比较的就不只是最近使用时长了,还会比较使用频率等条件。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://yundeesoft.com/6135.html