目录

  • redis淘汰机制
  • 淘汰策略
  • LRU算法
  • LFU算法
  • 如何获取及设置内存淘汰策略

redis淘汰机制

redis ttl 淘汰 redis的淘汰机制_Redis

淘汰策略

1.noeviction(默认策略):默认情况下,Redis 在使用的内存空间超过 maxmemory 值时,并不会淘汰数据,也就是设定的 noeviction 策略。对应到 Redis 缓存,也就是指,一旦缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误

2.volatile-lru:从设置了过期时间的key中使用LRU算法进行淘汰

3.volatile-random:在设置了过期时间的键值对中,进行随机删除。

4.volatile-ttl:在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。

5.volatile-lfu: 会使用 LFU 算法选择设置了过期时间的键值对。

5.allkeys-random:从所有键值对中随机选择并删除数据;

6.allkeys-lru:从所有key中使用LRU算法进行淘汰(LRU算法:即最近最少使用算法)

volatile-random、volatile-ttl、volatile-lru 和 volatile-lfu 这四种淘汰策略。它们筛选的候选数据范围,被限制在已经设置了过期时间的键值对上。也正因为此,即使缓存没有写满,这些数据如果过期了,也会被删除。

当使用volatile-lru、volatile-random、volatile-ttl这三种策略时,如果没有key可以被淘汰,则和noeviction一样返回错误

allkeys-lru、allkeys-random、allkeys-lfu 这三种淘汰策略的备选淘汰数据范围,就扩大到了所有键值对,无论这些键值对是否设置了过期时间。它们筛选数据进行淘汰的规则是:

LRU算法

(按照最近最少使用的原则来筛选数据)

把最新访问的数据放到链表的头部,其他数据依次后移(缺点:如果有大量数据被访问,就会带来很多链表移动操作,会很耗时,进而会降低 Redis 缓存性能)

Redis 默认会记录每个数据的最近一次访问的时间戳(由键值对数据结构 RedisObject 中的 lru 字段记录)。然后,Redis 在决定淘汰的数据时,第一次会随机选出 N 个数据,把它们作为一个候选集合。接下来,Redis 会比较这 N 个数据的 lru 字段,把 lru 字段值最小的数据从缓存中淘汰出去(把全部变成局部)

Redis 提供了一个配置参数 maxmemory-samples,这个参数就是 Redis 选出的数据个数 N。例如,我们执行如下命令,可以让 Redis 选出 100 个数据作为候选数据集:

CONFIG SET maxmemory-samples 100

当需要再次淘汰数据时,Redis 需要挑选数据进入第一次淘汰时创建的候选集合。这儿的挑选标准是:能进入候选集合的数据的 lru 字段值必须小于候选集合中最小的 lru 值。当有新数据进入候选数据集后,如果候选数据集中的数据个数达到了 maxmemory-samples,Redis 就把候选数据集中 lru 字段值最小的数据淘汰出去。

一、优先使用 allkeys-lru 策略。这样,可以充分利用 LRU 这一经典缓存算法的优势,把最近最常访问的数据留在缓存中,提升应用的访问性能。如果你的业务数据中有明显的冷热数据区分,建议使用 allkeys-lru 策略。

二、如果业务应用中的数据访问频率相差不大,没有明显的冷热数据区分,建议使用 allkeys-random 策略,随机选择淘汰的数据就行。

三、如果业务中有置顶的需求(也就是不能淘汰的数据),比如置顶新闻、置顶视频,那么,可以使用 volatile-lru 策略,同时不给这些置顶数据设置过期时间。这样一来,这些需要置顶的数据一直不会被删除,而其他数据会在过期时根据 LRU 规则进行筛选。

LFU算法

(从两个维度来筛选并淘汰数据:一是,数据访问的时效性(访问时间离当前时间的远近);二是,数据的被访问次数)

使用 LRU 策略时,由于 LRU 策略只考虑数据的访问时效,对于只访问一次的数据来说,LRU 策略无法很快将其筛选出来。而 LFU 策略在 LRU 策略基础上进行了优化,在筛选数据时,首先会筛选并淘汰访问次数少的数据,然后针对访问次数相同的数据,再筛选并淘汰访问时间最久远的数据。

LFU 缓存策略的优化LFU 缓存策略是在 LRU 策略基础上,为每个数据增加了一个计数器,来统计这个数据的访问次数。当使用 LFU 策略筛选淘汰数据时,首先会根据数据的访问次数进行筛选,把访问次数最低的数据淘汰出缓存。如果两个数据的访问次数相同,LFU 策略再比较这两个数据的访问时效性,把距离上一次访问时间更久的数据淘汰出缓存。

相对于 LRU 策略,Redis 只是把原来 24bit 大小的 lru 字段,又进一步拆分成了 16bit 的 ldt 和 8bit 的 counter,分别用来表示数据的访问时间戳和访问次数。

如何获取及设置内存淘汰策略

1、获取当前内存淘汰策略:

127.0.0.1:6379> config get maxmemory-policy

可以看到当前使用的默认的noeviction策略

2、获取Redis能使用的最大内存大小

127.0.0.1:6379> config get maxmemory

如果不设置最大内存大小或者设置最大内存大小为0,在64位操作系统下不限制内存大小,在32位操作系统下最多使用3GB内存。32 位的机器最大只支持 4GB 的内存,而系统本身就需要一定的内存资源来支持运行,所以 32 位机器限制最大 3 GB 的可用内存

3、设置淘汰策略

通过配置文件设置淘汰策略(修改redis.conf文件):

maxmemory-policy allkeys-lru

通过命令修改淘汰策略:

127.0.0.1:6379> config set maxmemory-policy allkeys-lru

4、设置Redis最大占用内存大小

#设置Redis最大占用内存大小为100M
127.0.0.1:6379> config set maxmemory 100mb