Redis内存回收策略

Redis可能因内存不足出错或回收过久致系统停顿,了解其回收策略很重要。当内存达最大值,可配置淘汰键值。介绍了如volatile - lru、allkeys - lru等多种策略,还提及默认策略、算法特性、参数影响及回收策略的优缺点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Redis会因为内存不足而产生错误,也会因为回收过久而导致系统长期的停顿,因此了解掌握Redis的回收策略十分重要。当Redis的内存达到规定的最大值时,可以进行配置进行淘汰键值,并且将一些键值对进行回收。

我们打开Redis安装目录下的redis.conf文件。配置文件中有这么一段话

# Set a memory usage limit to the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU or LFU cache, or to
# set a hard memory limit for an instance (using the 'noeviction' policy).
#
# WARNING: If you have slaves attached to an instance with maxmemory on,
# the size of the output buffers needed to feed the slaves are subtracted
# from the used memory count, so that network problems / resyncs will
# not trigger a loop where keys are evicted, and in turn the output
# buffer of slaves is full with DELs of keys evicted triggering the deletion
# of more keys, and so forth until the database is completely emptied.
#
# In short... if you have slaves attached it is suggested that you set a lower
# limit for maxmemory so that there is some free RAM on the system for slave
# output buffers (but this is not needed if the policy is 'noeviction').
#
# maxmemory <bytes>

# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones with an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
#
# LRU means Least Recently Used
# LFU means Least Frequently Used
#
# Both LRU, LFU and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# Note: with any of the above policies, Redis will return an error on write
#       operations, when there are no suitable keys for eviction.
#
#       At the date of writing these commands are: set setnx setex append
#       incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
#       sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
#       zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
#       getset mset msetnx exec sort
#
# The default is:
#
# maxmemory-policy noeviction

# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. For default Redis will check five keys and pick the one that was
# used less recently, you can change the sample size using the following
# configuration directive.
#
# The default of 5 produces good enough results. 10 Approximates very closely
# true LRU but costs more CPU. 3 is faster but not very accurate.
#
# maxmemory-samples 5
  • volatile-lru:采用最近使用最少的淘汰策略,Redis将回收那些超时的(仅仅是超时的)键值对,也就是它只淘汰那些超时的键值对。

  • allkeys-lru:采用最近最少使用的淘汰策略,Redis将对所有(不仅仅是超时的)的键值对采用最近最少使用的淘汰策略。

  • volatile-lfu:采用最近最不常用的淘汰策略,所谓最近最不常用,也就是一定时期内被访问次数最少的。Redis将回收超时的键值对。

  • allkeys-lfu:采用最近最不常用的淘汰策略,Redis将对所有的键值对采用最近最不常用的淘汰策略。

  • volatile-random:采用随机淘汰策略删除超时的键值对。

  • allkeys-random:采用随机淘汰策略删除所有的键值对,这个策略不常用。

  • volatile-ttl:采用删除存活时间最短的键值对策略。

  • noeviction:不淘汰任何键值对,当内存满时,如果进行读操作,例如get命令,它将正常工作,而做写操作,它将返回错误,也就是说,当Redis采用这个策略内存达到最大的时候,它就只能读不能写了。

Redis默认采用noeviction策略。

LRU算法或者TTL算法都是不精确的算法,而是一个近似算法。

Redis不会通过对全部的键值对进行比较来确定最精确的时间值,因为这太消耗时间,导致回收垃圾占用的时间太多造成服务器卡顿。在配置文件中,有一个参数maxmemory-samples,它的默认值是5,如果采用volatile-ttl算法,我们可以看看下面这个过程,假设有7个即将超时的键值对

键值对剩余超时秒数备注
A16属于探测样本
A23属于探测样本
A34属于探测样本
A45属于探测样本
A52属于弹出样本中的最小值,因此最先删除
A61虽然是最短值,但不属于探测样本,因此没有被删除

当设置maxmemory-samples越大,则Redis删除的就越精确,但消耗CPU。

回收超时策略的缺点是必须指明超时的键值对,这会给程序开发带来一些设置超时的代码,增加刘开发者的工作量。对所有的键值对进行回收,有可能把正在使用的键值对删掉,增加了存储的不稳定性。对于垃圾回收的策略,还需要控制回收的时间。

### Redis 内存淘汰策略详解 Redis 是一种基于内存的键值存储系统,在实际运行过程中可能会遇到内存不足的情况。为了应对这种情况,Redis 提供了几种不同的内存淘汰策略来管理可用内存。 #### 常见的内存淘汰策略 以下是几种常见的 Redis 内存淘汰策略及其工作原理: 1. **noeviction**: 当内存达到上限时,新写入操作会返回错误,而不会删除任何现有数据[^1]。 2. **allkeys-lru**: 删除最近最少使用的键(Least Recently Used, LRU),适用于大多数缓存场景。 3. **volatile-lru**: 仅针对设置了过期时间的键执行 LRU 淘汰策略。 4. **allkeys-random**: 随机删除任意键,适合于不需要精确控制哪些数据被保留的应用场景。 5. **volatile-random**: 只随机删除带有 TTL(Time To Live)属性的键。 6. **volatile-ttl**: 优先删除即将到期的数据项,即具有较短剩余生存时间的键。 每种策略都有其特定适用范围和优缺点,因此选择哪种策略取决于具体应用场景的需求。 #### 如何配置 Redis内存淘汰策略? 可以通过修改 `redis.conf` 文件中的参数或者通过命令动态调整来设置相应的淘汰机制。下面展示两种方式实现这一目标的方法: - 修改配置文件:打开 redis 安装目录下的 `redis.conf` 文件找到并编辑如下行: ```conf maxmemory-policy noeviction ``` 将上述行更改为期望采用的具体政策名称即可生效;例如切换至 allkeys-lru,则应设为: ```conf maxmemory-policy allkeys-lru ``` - 使用 CONFIG SET 命令实时更改当前实例的行为而不重启服务: ```bash CONFIG SET maxmemory-policy volatile-lru ``` 注意每次改动后需确认新的设定已被接受且正确实施,可通过以下指令查看现况状态: ```bash CONFIG GET maxmemory* ``` 此命令将显示目前的最大允许容量以及所选的回收方案详情。 #### 工作流程概述 当 Redis 达到指定最大内存限制(`maxmemory`)之后,它便会依据选定好的淘汰算法自动清理部分占用空间较大的对象以便腾出更多位置给新增加的内容。整个过程完全自动化无需人为干预,但合理规划初始分配量级与挑选恰当清除法则对于维持高效稳定的服务至关重要。 ```python import redis # 创建连接池 pool = redis.ConnectionPool(host='localhost', port=6379, decode_responses=True) r = redis.Redis(connection_pool=pool) # 设置最大内存大小 (单位字节),这里假设为 1GB r.config_set('maxmemory', '1073741824') # 设定淘汰策略为 allkeys-lru r.config_set('maxmemory-policy', 'allkeys-lru') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值