Redis 内存淘汰策略深度解析(最新推荐)

2025-03-10 17:50

本文主要是介绍Redis 内存淘汰策略深度解析(最新推荐),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《Redis内存淘汰策略深度解析(最新推荐)》本文详细探讨了Redis的内存淘汰策略、实现原理、适用场景及最佳实践,介绍了八种内存淘汰策略,包括noeviction、LRU、LFU、TTL、Rand...

Redis 作为高性能的内存数据库,其内存资源的高效管理直接关系到系统的稳定性yorckf和性能。当 Redis 的内存使用达到配置的最大值(maxmemory)时,新的写入操作将触发内存淘汰机制(Eviction Policy),以释放空间存储新数据。本文将深入探讨 Redis 的内存淘汰策略、实现原理、适用场景及最佳实践。

一、 内存淘汰策略概述

Redis 的内存淘汰策略决定了在内存不足时,如何选择需要删除的键来释放空间。这些策略可以分为两大类:

  • 基于过期时间的淘汰​(volatile-*):仅针对设置了过期时间的键。
  • 全局淘汰​(allkeys-*):针对所有键,无论是否设置过期时间。

Redis 支持以下 8 种内存淘汰策略

noeviction:默认策略,禁止写入新数据,直接返回错误。
volatile-lru:淘汰最近最少使用(LRU)的设置了过期时间的键。
volatile-lfu:淘汰最不经常使用(LFU)的设置了过期时间的键。
volatile-random:随机淘汰设置了过期时间的键。
volatile-ttl:优先淘汰剩余生存时间(TTL)最短的键。
allkeys-lru:淘汰所有键中最近最少使用的键。
allkeys-lfu:淘汰所有键中最不经常使用的键。
allkeys-random:随机淘汰任意键。

二、内存淘汰策略详解

2.1 ​noeviction(不淘汰)​

​行为:当内存不足时,拒绝所有写入命令(如 SET、LPUSH),但允许读取操作。
​适用场景:适用于数据不可丢失的场景(如持久化存储),需确保内存足够或配合持久化机制。
缺点:若内存不足且无持久化,可能导致服务不可用。

2.2 ​LRU(Least Recently Used)​

​原理:淘汰最近最久未被访问的键。
​Redis 实现:Redis 使用近似 LRU 算法,通过随机采样(默认取 5 个键)选择最久未使用的键,而非遍历所有键,以减少计算开销。
​适用场景:适用于缓存场景,优先保留热点数据。
​命令示例

CONFIG SET maxmemory-policy volatile-lru  # 针对带过期时间的键
CONFIG SET maxmemory-policy allkeys-lru   # 针对所有键

2.3 ​LFU(Least Frequently Used)​

​原理:淘汰访php问频率最低的键(Redis 4.0 引入)。
​Redis 实现:通过计数器统计键的访问频率,并随时间衰减历史计数,避免长期累积导致无法淘汰旧键。
​适用场景:适合长期缓存,如高频访问的静态数据。
​命令示例

CONFIG SET maxmemory-policy volatile-lfu  # 针对带过期时间的键
CONFIG SET maxmemory-policy allkeys-lfu   # 针对所有键

2.4 ​TTL(Time To Live)​

​原理:优先淘汰剩余生存时间(TTL)最短的键。
​适用场景:适用于明确知道键生命周期的场景(如临时会话数据)。
限制:仅对设置了过期时间的键生效。
​命令示例

CONFIG SET maxmemory-policy volatile-ttl

2.5 ​Random(随机淘汰)​

​原理:随机选择键进行淘汰。
​适用场景:内存压力大且数据重要性均等时,快速释放内存。
​命令示例

CONFIG SET maxmemory-policy volatile-random  # 针对带过期时间的键
CONFIG SET maxmemory-policy allkeys-random   # 针对所有键

三、 内存淘汰的底层实现

3.1 ​LRU/LFU 的近似算法

  • Redis 通过 ​evictionPoolEntry​结构维护候选淘汰键池。每次淘汰时,随机采样一组键,更新其访问时间或频率信息,选择最不活跃的键删除。
  • ​LRU 时钟:Redis 使用全局 24 位时钟(精度为秒)记录键的最近访问时间。内存中每个对象存储与全局时钟的差值(lru字段),而非精确时间戳。
  • ​LFU 计数器:每个键的 lru 字段被拆分为两部分:
    • 高 16 位:最近访问时间的分钟级精度。
    • 低 8 位:访问频率计数器(0~255),通过概率递增,随时间衰减。

3.2 ​淘汰流程

  • 客户端执行写入命令触发内存检查。
  • Redis 检查 maxmemory 是否已超出。
  • 根据配置的策略选择待淘汰键。
  • 删除键并触发相javascript关事件(如 evicted 通知)。

四、 如何选择合适的内存淘汰策略?

4.1 ​缓存场景

http://www.chinasem.cn推荐策略:allkeys-lru 或 allkeys-lfu
​理由:优先保留热点数据,最大化缓存命中率。

4.2 ​持久化存储

​推荐策略:noeviction(需确保内存足够或启用持久化)。
​替代方案:若允许部分数据丢失,可使用 volatile-lru 结合过期时间。

4.3 ​临时数据场景

​推荐策略:volatile-ttl
​理由:自动清理生命周期明确的数据(如验证码、会话信息)。

4.4 ​混合型数据

​推荐策略:allkeys-lru + 部分键设置过期时间。
​示例:电商系统中,商品详情用 allkeys-lru 缓存,购物车数据设置 TTL。

五、最佳实践与注意事项

5.1 ​配置建议

​设置合理的 maxmemory:通常为物理内存的 80%~90%,避免 OOM。
​监控内存使用:

INFO memory  # 查看内存指标(used_memory、maxmemory)
INFO stats    # 查看 evicted_keys(淘汰键数量)

5.2 ​避免大规模淘汰

​分片设计:通过集群分散数据,减少单个节点的内存压力。
​预热缓存:重启后预加载高频数据,避免冷启动时集中淘汰。

5.3 ​常见误区

volatile-ttl 不依赖惰性删除:该策略仅在内存不足时触发,仍需依赖定期/惰性删除清理过期键。
​LFU 计数器并非精确值:访问频率通过概率递增,适用于相对比较而非绝对计数。

六、总结

Redis 的内存淘汰策略是平衡内存使用与性能的关键机制。理解不同策略的原理和适用场景,结合业务需求合理配置,可显著提升系统的稳定性和效率。在高并发场景下,建议通过监控工具(如 RedisInsight、Prometheus)实时跟踪内存和淘汰指标,动态调整策略和资源配置。

通过本文的深度解析,希望您能掌握 Redis 内存淘汰的核心机制,并在实践中灵活运用,构建高效可靠的 Redis 服务。

参考资料

Redis 官方文档:https://redis.io/docs/reference/eviction/
《Redis 设计与实现》——黄健宏
Redis 源码解析(evict.c、object.c)

到此这篇关于Redis 内存淘汰策略深度解析的文章就介绍到这了,更多相关Redis 内存淘汰策略内容请搜索China编程(www.chinasem.cn)以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程China编程(www.chinasem.cn)!

这篇关于Redis 内存淘汰策略深度解析(最新推荐)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1153681

相关文章

Redis 的 SUBSCRIBE命令详解

《Redis的SUBSCRIBE命令详解》Redis的SUBSCRIBE命令用于订阅一个或多个频道,以便接收发送到这些频道的消息,本文给大家介绍Redis的SUBSCRIBE命令,感兴趣的朋友跟随... 目录基本语法工作原理示例消息格式相关命令python 示例Redis 的 SUBSCRIBE 命令用于订

深度解析Python中递归下降解析器的原理与实现

《深度解析Python中递归下降解析器的原理与实现》在编译器设计、配置文件处理和数据转换领域,递归下降解析器是最常用且最直观的解析技术,本文将详细介绍递归下降解析器的原理与实现,感兴趣的小伙伴可以跟随... 目录引言:解析器的核心价值一、递归下降解析器基础1.1 核心概念解析1.2 基本架构二、简单算术表达

深度解析Java @Serial 注解及常见错误案例

《深度解析Java@Serial注解及常见错误案例》Java14引入@Serial注解,用于编译时校验序列化成员,替代传统方式解决运行时错误,适用于Serializable类的方法/字段,需注意签... 目录Java @Serial 注解深度解析1. 注解本质2. 核心作用(1) 主要用途(2) 适用位置3

sky-take-out项目中Redis的使用示例详解

《sky-take-out项目中Redis的使用示例详解》SpringCache是Spring的缓存抽象层,通过注解简化缓存管理,支持Redis等提供者,适用于方法结果缓存、更新和删除操作,但无法实现... 目录Spring Cache主要特性核心注解1.@Cacheable2.@CachePut3.@Ca

Java MCP 的鉴权深度解析

《JavaMCP的鉴权深度解析》文章介绍JavaMCP鉴权的实现方式,指出客户端可通过queryString、header或env传递鉴权信息,服务器端支持工具单独鉴权、过滤器集中鉴权及启动时鉴权... 目录一、MCP Client 侧(负责传递,比较简单)(1)常见的 mcpServers json 配置

Redis实现高效内存管理的示例代码

《Redis实现高效内存管理的示例代码》Redis内存管理是其核心功能之一,为了高效地利用内存,Redis采用了多种技术和策略,如优化的数据结构、内存分配策略、内存回收、数据压缩等,下面就来详细的介绍... 目录1. 内存分配策略jemalloc 的使用2. 数据压缩和编码ziplist示例代码3. 优化的

redis-sentinel基础概念及部署流程

《redis-sentinel基础概念及部署流程》RedisSentinel是Redis的高可用解决方案,通过监控主从节点、自动故障转移、通知机制及配置提供,实现集群故障恢复与服务持续可用,核心组件包... 目录一. 引言二. 核心功能三. 核心组件四. 故障转移流程五. 服务部署六. sentinel部署

从原理到实战解析Java Stream 的并行流性能优化

《从原理到实战解析JavaStream的并行流性能优化》本文给大家介绍JavaStream的并行流性能优化:从原理到实战的全攻略,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的... 目录一、并行流的核心原理与适用场景二、性能优化的核心策略1. 合理设置并行度:打破默认阈值2. 避免装箱

Maven中生命周期深度解析与实战指南

《Maven中生命周期深度解析与实战指南》这篇文章主要为大家详细介绍了Maven生命周期实战指南,包含核心概念、阶段详解、SpringBoot特化场景及企业级实践建议,希望对大家有一定的帮助... 目录一、Maven 生命周期哲学二、default生命周期核心阶段详解(高频使用)三、clean生命周期核心阶

深入解析C++ 中std::map内存管理

《深入解析C++中std::map内存管理》文章详解C++std::map内存管理,指出clear()仅删除元素可能不释放底层内存,建议用swap()与空map交换以彻底释放,针对指针类型需手动de... 目录1️、基本清空std::map2️、使用 swap 彻底释放内存3️、map 中存储指针类型的对象