导读:本期聚焦于小伙伴创作的《Redis过期键删除策略与内存淘汰机制详解:惰性删除、定期删除及LRU/LFU》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《Redis过期键删除策略与内存淘汰机制详解:惰性删除、定期删除及LRU/LFU》有用,将其分享出去将是对创作者最好的鼓励。

Redis 过期策略及内存回收机制解析

Redis 作为高性能的内存数据库,在实际使用中需要合理管理内存资源,避免内存溢出导致的服务异常。其中过期键的处理和内存回收机制是 Redis 内存管理的核心内容,本文将详细解析这两部分的工作原理。

一、Redis 过期策略

Redis 支持为键设置过期时间,当键到达过期时间后,需要按照一定的策略进行处理,同时不影响 Redis 的正常读写性能。Redis 采用的是惰性删除 + 定期删除组合策略。

1.1 惰性删除

惰性删除是指当客户端访问某个键时,Redis 会先检查该键是否设置了过期时间,以及是否已经过期。如果键已过期,则直接删除该键,然后返回空结果;如果键未过期,则正常返回键值。

这种策略的优点是 CPU 友好,只会在访问键的时候才进行过期检查,不会额外消耗 CPU 资源;缺点是内存不友好,如果过期键长期没有被访问,会一直占用内存空间。

以下是惰性删除的核心逻辑伪代码:

def get_key(key):
    # 检查键是否设置过期时间,且已过期
    if key in expire_dict and expire_dict[key] < current_time():
        delete_key(key)
        return None
    return storage.get(key)

1.2 定期删除

定期删除是指 Redis 会周期性地(默认每秒 10 次)随机抽查一部分设置了过期时间的键,检查它们是否过期,如果过期则删除。定期删除是对惰性删除的补充,避免大量过期键长期占用内存。

定期删除的执行流程如下:

  • 从设置了过期时间的键集合中,随机选择一批键(默认 20 个)

  • 遍历这批键,删除其中已过期的键

  • 如果这批键中过期键的比例超过 25%,则重复上述步骤,直到过期键比例低于 25% 或者达到执行时间上限

通过调整定期删除的频率和每次抽查的键数量,可以在 CPU 消耗和内存释放之间取得平衡。默认配置已经能满足大部分场景的需求,一般不需要手动修改。

二、Redis 内存回收机制

当 Redis 占用的内存达到预设的最大内存限制(通过 maxmemory 配置项设置)时,会触发内存回收机制,按照指定的淘汰策略删除部分键,释放内存空间。Redis 提供了 8 种淘汰策略,用户可以根据业务场景选择合适的策略。

2.1 淘汰策略分类

Redis 的淘汰策略可以分为以下几类:

策略名称策略说明适用场景
noeviction不淘汰任何键,当内存不足时,新写入操作会报错,读操作和删除操作正常执行数据不能丢失的场景,比如缓存+持久化存储结合的场景
allkeys-lru从所有键中淘汰最近最少使用的键(LRU 算法)缓存场景,希望保留最常访问的数据
volatile-lru从设置了过期时间的键中淘汰最近最少使用的键部分键设置过期时间的缓存场景
allkeys-random从所有键中随机淘汰键所有键访问频率相近的缓存场景
volatile-random从设置了过期时间的键中随机淘汰键部分键设置过期时间的随机淘汰场景
volatile-ttl从设置了过期时间的键中,淘汰剩余存活时间最短的键希望优先淘汰即将过期的键的场景
allkeys-lfu从所有键中淘汰使用频率最低的键(LFU 算法,Redis 4.0 及以上支持)需要统计键访问频率的缓存场景
volatile-lfu从设置了过期时间的键中淘汰使用频率最低的键(LFU 算法,Redis 4.0 及以上支持)部分键设置过期时间的 LFU 淘汰场景

2.2 LRU 与 LFU 算法说明

LRU(Least Recently Used)即最近最少使用,核心思想是淘汰一段时间内最久没有被访问的键。Redis 中的 LRU 算法是近似 LRU,并非严格实现,因为严格 LRU 需要维护所有键的访问时间链表,会消耗大量内存和 CPU 资源。Redis 给每个键维护一个 24 位的时钟字段,记录最近一次访问的时间戳,淘汰时随机采样一批键,选择时间戳最小的(最久未访问的)进行淘汰。

LFU(Least Frequently Used)即最少使用频率,核心思想是淘汰一段时间内访问次数最少的键。和 LRU 相比,LFU 更关注键的访问频率,适合访问频率差异较大的场景。Redis 中的 LFU 会给每个键维护一个访问计数器和衰减时间,访问时计数器增加,同时会定期根据衰减时间降低计数器值,避免旧的热键一直占用内存。

2.3 内存回收的执行流程

当 Redis 执行写命令时,会先检查当前内存使用是否超过 maxmemory 限制,如果超过,则按照配置的淘汰策略执行淘汰操作,直到内存使用低于限制后再执行写命令。如果淘汰后仍然无法满足内存需求,写命令会返回错误(noeviction 策略下直接返回错误)。

以下是内存回收的简化流程伪代码:

def execute_write_command(cmd):
    # 检查内存是否超过限制
    while used_memory() > maxmemory:
        # 执行淘汰策略,删除键释放内存
        evict_keys()
        # 如果淘汰策略返回 False,说明无法继续淘汰
        if not evict_keys():
            if maxmemory_policy == 'noeviction':
                return error("OOM command not allowed when used memory > 'maxmemory'")
    # 执行写命令
    return do_write(cmd)

三、实际配置建议

在实际使用 Redis 时,可以根据业务需求合理配置过期策略和内存回收机制:

  • 如果作为纯缓存使用,建议设置 maxmemory 为服务器可用内存的 70%-80%,避免 Redis 占用过多内存影响其他服务

  • 缓存场景下优先选择 allkeys-lruallkeys-lfu 策略,根据业务访问特征选择 LRU 或 LFU

  • 如果需要区分缓存键和持久化键,可以给缓存键设置过期时间,选择 volatile-lru 等 volatile 开头的策略

  • 不需要手动调整定期删除的频率,默认配置已经做了性能平衡,特殊场景可以参考 Redis 官方文档调整 hz 配置项

注意:Redis 的过期键删除和内存淘汰都不会触发持久化操作,删除的键会在后续的 AOF 重写或者 RDB 生成时从持久化文件中移除。

Redis过期策略 内存回收机制 LRU算法 LFU算法 淘汰策略配置

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。