Redis缓存满了怎么办?

目录

引言

Redis最大运行内存

查询最大运行内存

内存淘汰策略

查看Redis内存淘汰策略

内存淘汰策略分类

修改Redis内存淘汰策略

内存淘汰算法

LRU算法

LFU算法

总结


引言

​        Redis缓存使用内存来保存数据,随着需要缓存的数据量越来越大,有限的缓存空间不可避免地会被写满。此时,应该怎么办?接下来就来聊聊缓存满了之后的数据淘汰机制。

​        值得注意的是,在Redis中过期策略内存淘汰策略是两个完全不同的概念。Redis过期策略指的是Redis使用那种策略来删除已经过期的键值对,而内存淘汰机制指的是当Redis运行内存已经超过设置的最大内存之后,将采用什么策略来删除符合条件的键值对,以此来保障Redis高效的运行。

Redis最大运行内存

​        只有在Redis的运行内存达到了某个阀值,才会触发内存淘汰机制,这个阀值就是我们设置的最大运行内存,此值在Redis的配置文件中可以找到,配置项为maxmenmory。

​ 内存淘汰执行流程如下所示:

​ ① 客户端发送命令

​ ② 服务器端检查maxmemory是否大于0(是→③,否→⑤)

​ ③ 检查运行内存是否大于maxmemory(是→④,否→⑤)

​ ④ 执行淘汰策略

​ ⑤ 结束

查询最大运行内存

​        我们可以使用命令config get maxmemory来查看设置的最大运行内存,命令如下:

127.0.0.1:6379> config get maxmemory
1) "maxmemory"
2) "0"

​        我们发现此值竟然是0,这是64位操作系统默认的值,当maxmemory为0时,表示没有内存大小限制。

​        注意:32位操作系统,默认的最大内存值是3GB。

内存淘汰策略

查看Redis内存淘汰策略

​        我们可以使用config get maxmemory-policy命令,来查看当前Redis的内存淘汰策略,命令如下:

127.0.0.1:6379> config get maxmemory-policy
1) "maxmemory-policy"
2) "noeviction"

​        可以看出此Redis使用的是noeviction类型的内存淘汰机制,它表示当运行内存超过最大设置内存时,不淘汰任何数据,但新增操作会报错。

内存淘汰策略分类

​        早期版本的Redis有以下6种淘汰策略:

  1. noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis默认内存淘汰策略;

  2. allkeys-lru:淘汰整个键值中最久未使用的键值;

  3. allkeys-random:随机淘汰任意键值;

  4. volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;

  5. volatile-random:随机淘汰设置了过期时间的任意键值;

  6. volatile-ttl:优先淘汰更早过期的键值。

    在Redis4.0版本中又新增了2中淘汰策略:

  7. volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;

  8. allkeys-lfu:淘汰整个键值中最少使用的键值。

    其中allkeys-xxx表示从所有的键值中淘汰数据,而volatile-xxx表示设置了过期键的键值中淘汰数据。

修改Redis内存淘汰策略

​        设置内存淘汰策略有两种方法,这两种方法各有利弊,需要使用者自己去权衡。

  • 方式一:通过“config set maxmemory-policy”命令设置。它的优点是设置之后立即生效,不需要重启Redis服务,缺点是重启Redis之后,设置就会失效。
  • 方式二:通过修改Redis配置文件修改,设置“maxmemory-policy”,它的优点是重启Redis服务后配置不会丢失,缺点是必须重启Redis服务,设置才能生效。

内存淘汰算法

​        从内存淘汰策略分类上,我们可以得知,除了随机删除和不删除之外,主要有两种淘汰算法:LRU算法和LFU算法。

LRU算法

​        LRU全称是Least Recently Used,翻译为最近最少使用,是一种常用的页面置换算法,选择最近最久未使用的页面予以淘汰。

  1. LRU算法实现

    LRU算法需要基于链表结构,链表中的元素按照操作顺序从前往后排列,最新操作的键会被移动到表头,当需要内存淘汰时,只需要删除链表尾部的元素即可。

  2. 近LRU算法

    Redis使用的是一种近似LRU算法,目的是为了更好的节约内存,它的实现方式是给现有的数据结构添加一个额外的字段,用于记录此键值的最后一次访问时间,Redis内存淘汰时,会使用随机采样的方式来淘汰数据,它是随机取5个值(此值可配置),然后淘汰最久没有使用的那个。

  3. LRU算法缺点

    LRU算法有一个缺点,比如说很久没有使用的一个键值,如果最近被访问了一次,那么它就不会被淘汰,即使它是使用次数最少的缓存,那它也不会被淘汰,因此在Redis4.0之后引入了LFU算法,下面我们一起来看看。

LFU算法

​        LFU全称是Least Frequently Used,翻译为最不常用的,最不常用的算法是根据总访问次数来淘汰数据的,它的核心思想是“如果数据过去被访问多次,那么将来被访问的频率也更高”。

​        LFU解决了偶尔被访问一次之后,数据就不会被淘汰的问题,相比于LRU算法也更合理一些。

​        在Redis中每个对象头中记录着LFU的信息,源码如下:

typedef struct redisObject {
    unsigned type:4;
    unsigned encoding:4;
    unsigned lru:LRU_BITS; /* LRU time (relative to global lru_clock) or
    						* LFU data (least significant 8 bits frequency
    						* and most significant 16 bits access time). */
    int refcount;
    void *ptr;				
} robj;

​        在Redis中LFU存储分为两部分,16bit的ldt(last decrement time)和8bit的logc(logistic counter)。

  1. logc是用来存储访问频次,8bit能表示的最大整数为255,它的值越小表示使用的频率越低,越容易淘汰;
  2. ldt是用来存储上一次logc的更新时间。

总结

​        综上所述我们了解到,Redis内存淘汰策略和过期回收策略是完全不同的概念,内存淘汰策略是解决Redis运行内存过大的问题的,通过与maxmemory比较,决定要不要淘汰数据,根据maxmemory-policy参数,决定使用何种淘汰策略,在Redis4.0之后已经有8种淘汰策略了,默认的策略是noeviction当内存超出时不淘汰任何键值,只是新增操作会报错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值