数据结构论坛

首页 » 分类 » 定义 » Redis内存淘汰机制详解
TUhjnbcbe - 2021/8/17 23:26:00

一般来说,缓存的容量是小于数据总量的,所以,当缓存数据越来越多,Redis不可避免的会被写满,这时候就涉及到Redis的内存淘汰机制了。我们需要选定某种策略将“不重要”的数据从Redis中清除,为新的数据腾出空间。

1、配置Redis内存大小

我们应该为Redis设置多大的内存容量呢?

根据“八二原理“,即80%的请求访问了20%的数据,因此如果按照这个原理来配置,将Redis内存大小设置为数据总量的20%,就有可能拦截到80%的请求。当然,只是有可能,对于不同的业务场景需要进行不同的配置,一般建议把缓存容量设置为总数据量的15%到30%,兼顾访问性能和内存空间开销。

配置方式(以5GB为例,如果不带单位则默认单位是字节):

命令行

configsetmaxmemory5gb

配置文件

查看maxmemory命令

configgetmaxmemory

2、Redis的内存淘汰策略

在Redis4.0版本之前有6种策略,4.0增加了2种,主要新增了LFU算法。

下图为Redis6.2.0版本的配置文件:

其中,默认的淘汰策略是noevition,也就是不淘汰

我们可以对8种淘汰策略可以分为两大类:

不进行淘汰的策略

noevition,此策略不会对缓存的数据进行淘汰,当内存不够了就会报错,因此,如果真实数据集大小大于缓存容量,就不要使用此策略了。

会进行淘汰的策略

allkeys-random:随机删除

allkeys-lru:使用LRU算法进行筛选删除

allkeys-lfu:使用LFU算法进行筛选删除

volatile-random:随机删除

volatile-ttl:根据过期时间先后进行删除,越早过期的越先被删除

volatile-lru:使用LRU算法进行筛选删除

volatile-lfu:使用LFU算法进行筛选删除

在设置了过期时间的数据中筛选

在所有数据中筛选

以volatile开头的策略只针对设置了过期时间的数据,即使缓存没有被写满,如果数据过期也会被删除。

以allkeys开头的策略是针对所有数据的,如果数据被选中了,即使过期时间没到,也会被删除。当然,如果它的过期时间到了但未被策略选中,同样会被删除。

那么我们如何配置过期策略呢?

命令行

configsetmaxmemory-policyallkeys-lru

配置文件

3、LRU算法

首先简单介绍一下LRU算法:

LRU全称是LeastRecentlyUsed,即最近最少使用,会将最不常用的数据筛选出来,保留最近频繁使用的数据。

LRU会把所有数据组成一个链表,链表头部称为MRU,代表最近最常使用的数据;尾部称为LRU代表最近最不常使用的数据;

下图是一个简单的例子:

但是,如果直接在Redis中使用LRU算法也会有一些问题:

LRU算法在实现过程中使用链表管理所有缓存的数据,这会给Redis带来额外的开销,而且,当有数据访问时就会有链表移动操作,进而降低Redis的性能。

于是,Redis对LRU的实现进行了一些改变:

记录每个key最近一次被访问的时间戳(由键值对数据结构RedisObject中的lru字段记录)

在第一次淘汰数据时,会先随机选择N个数据作为一个候选集合,然后淘汰lru值最小的。(N可以通过configsetmaxmemory-samples命令来配置)

后续再淘汰数据时,会挑选数据进入候选集合,进入集合的条件是:它的lru小于候选集合中最小的lru。

如果候选集合中数据个数达到了maxmemory-samples,Redis就会将lru值小的数据淘汰出去。

4、LFU算法

LFU全称LeastFrequentlyUsed,即最不经常使用策略,它是基于数据访问次数来淘汰数据的,在Redis4.0时添加进来。它在LRU策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。

前面说到,LRU使用了RedisObject中的lru字段记录时间戳,lru是24bit的,LFU将lru拆分为两部分:

ldt值:lru字段的前16bit,表示数据的访问时间戳

counter值:lru字段的后8bit,表示数据的访问次数

使用LFU策略淘汰缓存时,会把访问次数最低的数据淘汰,如果访问次数相同,再根据访问的时间,将访问时间戳最小的淘汰。

为什么Redis有了LRU还需要LFU呢?

在一些场景下,有些数据被访问的次数非常少,甚至只会被访问一次。当这些数据服务完访问请求后,如果还继续留存在缓存中的话,就只会白白占用缓存空间。

由于LRU是基于访问时间的,如果系统对大量数据进行单次查询,这些数据的lru值就很大,使用LFU算法就不容易被淘汰。

-END-

长按进入小程序,进行授权登陆

(更多精彩值得期待……)

推荐我的

1
查看完整版本: Redis内存淘汰机制详解