Redis 缓存满了如何解决

 更新时间:2023年08月23日 08:51:32   作者:Genius Kim  
Redis 缓存使用内存来保存数据,随着需要缓存的数据量越来越大,有限的缓存空间不可避免地会被写满,本文主要介绍了Redis 缓存满了如何解决,感兴趣的可以了解一下

引言

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

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

Redis 最大运行内存

只有在 Redis 的运行内存达到了某个阀值,才会触发内存淘汰机制,这个阀值就是我们设置的最大运行内存,此值在 Redis 的配置文件中可以找到,配置项为 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 种淘汰策略:

  • noeviction:不淘汰任何数据,当内存不足时,新增操作会报错,Redis 默认内存淘汰策略;
  • allkeys-lru:淘汰整个键值中最久未使用的键值;
  • allkeys-random:随机淘汰任意键值;
  • volatile-lru:淘汰所有设置了过期时间的键值中最久未使用的键值;
  • volatile-random:随机淘汰设置了过期时间的任意键值;
  • volatile-ttl:优先淘汰更早过期的键值。

在 Redis 4.0 版本中又新增了 2 种淘汰策略:

  • volatile-lfu:淘汰所有设置了过期时间的键值中,最少使用的键值;
  • 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 算法有一个缺点,比如说很久没有使用的一个键值,如果最近被访问了一次,那么它就不会被淘汰,即使它是使用次数最少的缓存,那它也不会被淘汰,因此在 Redis 4.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 存储分为两部分,16 bit 的 ldt(last decrement time)和 8 bit 的 logc(logistic counter)。

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

总结

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

到此这篇关于Redis 缓存满了如何解决的文章就介绍到这了,更多相关Redis 缓存满了内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Redis集群Lettuce主从切换问题解决方案

    Redis集群Lettuce主从切换问题解决方案

    这篇文章主要为大家介绍了Redis集群Lettuce主从切换问题解决方案,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • 详解redis中的下载和安装(最新推荐)

    详解redis中的下载和安装(最新推荐)

    本文详细介绍了如何在Linux和Docker上安装、配置、启动和关闭Redis,包括下载安装包、解压、编译安装、配置文件修改、前台和后台启动、关闭以及Docker容器化部署等步骤,感兴趣的朋友一起看看吧
    2025-03-03
  • Redis搭建哨兵集群实践

    Redis搭建哨兵集群实践

    本文介绍了从零搭建一个1主+2从+3哨兵的高可用Redis架构,并验证故障转移效果,文中详细描述了环境准备、搭建Redis主从复制、配置哨兵集群、验证哨兵集群状态以及模拟故障转移的步骤,最后,还提供了在生产环境中的最佳实践和常见问题排查建议
    2026-04-04
  • Redis数据类型之散列类型hash命令学习

    Redis数据类型之散列类型hash命令学习

    这篇文章主要为大家介绍了Redis数据类型之散列类型hash命令学习,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • Redis如何使用HyperLogLog的实现

    Redis如何使用HyperLogLog的实现

    本文主要介绍了Redis如何使用HyperLogLog的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-06-06
  • Redis实现分布式限流的几种方法

    Redis实现分布式限流的几种方法

    Redis实现分布式限流能有效防止系统过载,,可以防止系统过载并确保公平的资源分配,主要算法包括固定窗口、滑动窗口和令牌桶,具有一定的参考价值,感兴趣的可以了解一下
    2026-01-01
  • Redis 数据类型Streams详解

    Redis 数据类型Streams详解

    Redis Streams是Redis 5.0新增的数据类型,提供了一种日志结构化数据存储方式,这种类型适合用于构建消息队列、事件日志和处理时间序列数据的应用,本文介绍Redis 数据类型Streams相关知识,感兴趣的朋友一起看看吧
    2024-10-10
  • 如何打造redis缓存组件

    如何打造redis缓存组件

    文章介绍了如何使用热插拔AOP、反射、Redis自定义注解和SpringEL表达式来打造一个优雅的Redis缓存组件,通过这种方式,可以重构和简化缓存代码,并提供了Redis配置和自定义注解的详细说明,文章还包含了AOP测试的总结,并鼓励读者参考和支持
    2024-12-12
  • Redis大Key问题识别、处理与预防全攻略

    Redis大Key问题识别、处理与预防全攻略

    Redis中的大Key就像血管中的血栓——单个Key过大(如100MB)会导致内存不均、操作阻塞、集群崩溃,必须及时溶栓,所以本文给大家介绍了Redis大Key问题识别、处理与预防全攻略,需要的朋友可以参考下
    2025-08-08
  • Windows系统一键启动Redis脚本

    Windows系统一键启动Redis脚本

    本文介绍了在Windows系统中创建一键启动Redis的脚本,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2024-12-12

最新评论