前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >Redis的键驱逐策略及数据过期删除策略

Redis的键驱逐策略及数据过期删除策略

作者头像
崔认知
发布2025-03-03 12:56:21
发布2025-03-03 12:56:21
7110
代码可运行
举报
文章被收录于专栏:nobody
运行总次数:0
代码可运行

Redis通常用作缓存,以加快对较慢服务器或数据库的读取访问。由于缓存条目是持久存储的数据的副本,因此当该高速缓存耗尽内存时,通常可以安全地将它们逐出(如果需要,将来可以再次缓存它们)。

Redis允许你指定驱逐策略,当该高速缓存的大小超过设定的内存限制时,自动驱逐键。每当客户端运行一个新的命令向该高速缓存添加更多数据时,Redis会检查内存使用情况。如果它大于限制,Redis会根据选择的回收策略回收键,直到使用的总内存回到限制以下。

请注意,当一个命令向该高速缓存添加大量数据时(例如,将一个大的集合交集存储到一个新的键中),这可能会暂时超过限制的大量数据。

以下各节说明了如何配置该高速缓存的内存限制,还介绍了可用的回收策略以及何时使用这些策略。

maxmemory 配置项:内存管理的关键设置

`maxmemory` 配置项是 Redis 中用于控制数据集内存使用量的重要参数。它允许用户设定 Redis 实例可以使用的最大内存量,从而有效管理内存资源,防止 Redis 占用过多内存导致系统性能下降或崩溃。

配置方法

用户可以通过以下两种方式设置 `maxmemory` 配置项:

1. 通过 `redis.conf` 文件配置:

- 打开 Redis 配置文件 `redis.conf`。

- 找到 `maxmemory` 配置项,修改其值为所需的内存大小。例如,设置最大内存为 100 MB:

代码语言:javascript
代码运行次数:0
复制
maxmemory 100mb

2. 通过 `CONFIG SET` 命令动态配置:

- 在 Redis 客户端中,使用 `CONFIG SET` 命令直接设置 `maxmemory`。例如,设置最大内存为 100 MB:

代码语言:javascript
代码运行次数:0
复制
 CONFIG SET maxmemory 100mb

配置示例

假设我们需要将 Redis 的最大内存设置为 100 MB,可以在 `redis.conf` 文件中进行如下配置:

代码语言:javascript
代码运行次数:0
复制
maxmemory 100mb

或者通过 `CONFIG SET` 命令动态设置:

代码语言:javascript
代码运行次数:0
复制
CONFIG SET maxmemory 100mb

配置说明

- 默认值:

- 在 64 位系统上,`maxmemory` 的默认值为 0,表示没有内存使用限制。

- 在 32 位系统上,`maxmemory` 的默认值为 3GB,这是 32 位系统地址空间的限制。

- 内存限制为零:

- 如果将 `maxmemory` 设置为 0,Redis 将不会对内存使用量进行任何限制。这在某些测试环境中可能有用,但在生产环境中应谨慎使用,以避免内存耗尽导致系统问题。

为复制或持久化实例设置maxmemory

如果您使用了 复制 或持久化 功能,Redis将使用一些RAM作为缓冲区来存储等待的更新集写入副本或AOF文件。 此缓冲区使用的内存不不会计入maxmemory的设置限制内

这是因为键的驱逐操作本身会产生更新数据,而这些更新数据必须被添加到缓冲区中。如果这些更新数据被计入已使用的内存,那么在某些情况下,通过驱逐键节省的内存会被立即用于缓冲区中的更新数据。这反过来又会触发更多的驱逐操作,由此产生的反馈循环可能会不必要地将许多项目从缓存中驱逐出去。

如果您正在使用复制或持久化功能,我们建议您设置 `maxmemory`,以便留出一些 RAM 来存储缓冲区。请注意,对于 `noeviction` 策略,这并不是必要的(有关驱逐策略的更多信息,请参见下面的部分)。

内存达到限制时键驱逐策略

当 Redis 的内存使用量达到 `maxmemory` 设置的限制时,Redis 会根据配置的 `maxmemory-policy` 参数决定如何处理。常见的策略包括:

noeviction:默认策略,当达到内存使用限制且客户端尝试执行可能会使用更多内存的命令时返回错误。

volatile-lru:删除设置了过期时间且最近最少使用的键(LRU淘汰算法)。

allkeys-lru:删除所有最近最少使用的键(LRU淘汰算法)。

volatile-lfu:删除设置了过期时间且最不经常使用的键(LFU淘汰算法)。

allkeys-lfu:删除所有最不经常使用的键(LFU淘汰算法)。

volatile-random:随机淘汰设置了过期时间的键。

allkeys-random:随机淘汰所有键。

volatile-ttl:根据过期时间淘汰设置了过期时间的键,越早过期越早淘汰。

通过合理配置 `maxmemory` 和 `maxmemory-policy`,可以有效管理 Redis 的内存使用,确保系统在高负载和大数据量的情况下仍能稳定运行。

作为一些经验法则,如下:

  • 当您预计只有一部分元素的访问频率会远高于其他元素时,请使用 `allkeys-lru` 策略。根据Pareto principle,这种情况非常常见,因此,如果您没有特别的理由偏好其他策略,`allkeys-lru` 是一个很好的默认选择。
  • 当您预计所有键的访问频率大致相等时,请使用 `allkeys-random` 策略。例如,当您的应用程序在重复循环中读取数据项时,就属于这种情况。
  • 如果您能够通过代码估算出哪些键是缓存淘汰的良好候选对象,并为它们设置较短的 TTL(存活时间),那么请使用 `volatile-ttl` 策略。此外,如果您能充分利用键的过期机制,那么您就不太可能遇到缓存内存限制的问题,因为许多键会在需要被淘汰之前就过期了。

`volatile-lru` 和 `volatile-random` 策略主要适用于您希望使用单个 Redis 实例来同时进行缓存以及存储一组持久化键的场景。然而,如果条件允许,您应考虑在这种情况下运行两个独立的 Redis 实例。

请注意,为键设置过期时间会消耗内存,因此像 `allkeys-lru` 这样的策略更加节省内存,因为它无需依赖过期时间即可执行操作。

LRU算法

LRU(Least Recently Used,最近最少使用)算法是根据数据在一段时间内是否被使用的记录来淘汰数据,该算法的核心思想是如果数据最近被使用,那么将来被使用的概率更高。可以把LRU算法理解为一个链表,会将新数据放在链表头部,在一段时间内,只要数据被使用就移到链表头部,链表满的时候就从链表尾部移出数据,即链表尾部的数据被淘汰。Redis中使用的算法近似于LRU算法,比如修改配置文件maxmemory–samples=5,表示在Redis中随机采样5个键,然后从中淘汰最少使用的键,因此采样键的数量与Redis库中键的数量越接近,淘汰的规则就越接近LRU算法。官方默认使用5个键,最多不超过10个键,越大就越消耗CPU的资源。采用LRU算法,如果一个热点数据在内存在LRU算法约定的时间段内没有被使用,非热点数据在这个时间段内反而被使用了,就可能误把热点数据淘汰了而留下非热点数据,因此在Redis 4版本后新增了LFU算法来解决这类问题。

LFU算法

LFU(Least Frequently Used,最近不常使用)算法根据数据使用的次数来淘汰数据,该算法的核心思想是如果数据过去被使用多次,那么将来被使用的频率更高。LFU算法反映了一个键的热度,不会像LRU算法中那样偶尔一次被使用就被误认为是热点数据。同样可以把LFU算法理解为一个链表,新数据放在链表尾部,链表中的数据按照被使用的次数降序排列,被使用次数相同的数据按最近使用的时间降序排列,链表满的时候从链表尾部移出数据。这样就避免了LRU算法可能存在的问题。需要注意的是LFU算法中数据使用的时间和使用次数(counter)。counter的衰减和两个配置有关。如果一个键长时间没有被使用,counter就会按衰减因子的值来减少,在衰减因子为1的情况下,N分钟没有访问,就要减N。

数据过期删除策略

内存没占满时,在Redis中过期的键是通过惰性删除和定期删除来进行优化的。•

惰性删除:当键被访问时检查该键的过期时间,如果过期就删除此键。未过期但是没有被访问的键仍存放在内存中,自然就继续占用内存资源。

定期删除:每隔一段时间,随机检查设置了过期的键并删除已过期的键。Redis每10秒进行一次过期扫描。第一步,随机取20个设置了过期策略的键。第二步,检查这20个键,删除其中已过期的键。第三步,如果有超过25%的键已过期则重复第一步。

主从架构和数据持久化对数据的过期处理

在RDB持久化模式中,采用全量持久化,所以在持久化的时候会过滤掉已经过期的键。在AOF持久化模式中,当出现键过期时就会给AOF文件发送删除命令。需要注意的是,在主从架构中,从节点从来不会主动删除过期的数据。为了保证数据一致性,主节点会发送删除命令给从节点来处理已经过期的键

翻译自:https://redis.io/docs/latest/develop/reference/eviction

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-03-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 认知科技技术团队 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为复制或持久化实例设置maxmemory
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档