Redis--基础知识点--26--过期删除策略 与 淘汰策略

Redis 的过期策略和淘汰策略是内存管理的核心机制,分别用于处理键的自动失效和内存不足时的数据清理。以下是详细说明:


1 、过期删除策略(Expiration Policy)

处理已设置过期时间(EXPIRE)的键,确保它们在过期后被删除。

1.1 被动删除(惰性删除)

  • 默认行为:始终启用,无需配置。
  • 触发时机:当客户端尝试访问某个键时,Redis 会检查其是否过期。
  • 行为:若键已过期,则直接删除并返回空结果,不返回数据。
  • 优点:仅在访问时检查,节省 CPU 资源。
  • 缺点:长期未被访问的过期键可能残留内存(需配合定期删除)。

1.2 定期删除(主动扫描)

  • 默认行为:始终启用,无需配置。
  • 触发时机:Redis 默认每秒 10 次随机抽查部分键。
  • 行为
    • 随机抽取 20 个设置了过期时间的键。
    • 删除其中已过期的键。
    • 若本轮删除的键超过 25%,重复流程(避免阻塞)。
  • 配置参数
    • hz 10:控制定期删除的频率(默认每秒 10 次)。
    • active-expire-effort:调整扫描强度(1-10,值越大越严格)。
  • 优点:平衡内存和性能,避免内存泄漏。
  • 缺点:无法保证及时删除所有过期键。

1.3. 过期键的存储

  • Redis 使用独立的字典(expires)记录键的过期时间,与主键字典分离。
  • 删除过期键时,会同时从主字典和 expires 字典中移除。

2 淘汰删除策略(Eviction Policy)

当内存达到 maxmemory 限制时,根据策略主动删除键以释放空间。

2.1 不淘汰(noeviction)

  • 行为:内存不足时,拒绝写入操作(返回错误),但允许读取和删除。
  • 适用场景:数据重要性高,不允许丢失(如分布式锁)。

2.2 LRU 策略(Least Recently Used)

  • allkeys-lru:从所有键中淘汰最久未使用的键。
  • volatile-lru:仅从设置了过期时间的键中淘汰最久未使用的键。
  • 实现 :Redis 使用近似 LRU 算法,维护一个随机采样的候选池(默认 5 个样本,可通过 maxmemory-samples 调整)。

2.3 LFU 策略(Least Frequently Used,Redis 4.0+)

  • allkeys-lfu:从所有键中淘汰访问频率最低的键。
  • volatile-lfu:仅从设置了过期时间的键中淘汰访问频率最低的键。
  • 实现:记录键的访问次数和衰减因子,优先淘汰冷数据。

2.4 随机策略

  • allkeys-random:从所有键中随机淘汰。
  • volatile-random:仅从设置了过期时间的键中随机淘汰。
  • 适用场景:数据无明显访问模式,需快速释放内存。

2.5 TTL 策略

  • volatile-ttl:仅淘汰设置了过期时间的键中,剩余生存时间(TTL)最短的键。
  • 适用场景:希望优先保留长期有效的数据。

2.6 策略对比与选择建议

策略 适用场景 特点
noeviction 禁止数据丢失(如缓存+数据库模式) 内存不足时阻塞写入
allkeys-lru 缓存场景,数据访问模式符合局部性 高效利用内存,推荐默认策略
volatile-lru 需结合过期时间使用 仅淘汰带过期时间的键
allkeys-lfu 访问频率差异大的数据 适合热点数据频繁访问的场景
volatile-ttl 希望短期数据优先淘汰 简单直接,但可能误删热点数据

2.7 最佳实践

  1. 缓存场景
    • 优先使用 allkeys-lruallkeys-lfu,结合 maxmemory-policy 配置。
    • 设置合理的 maxmemory(如系统内存的 60%-80%)。
  2. 持久化数据
    • 使用 noeviction,配合数据库做主从备份。
  3. 混合场景
    • 结合 volatile-ttlvolatile-lru,为部分键设置过期时间。

2.8 淘汰策略的其它问题

2.8.1 数据库有1000万数据,Redis只能缓存20w数据,如何保证Redis中的数据都是热点数据 ?

使用allkeys-lru(挑选最近最少使用的数据淘汰)淘汰策略,留下来的都是经常访问的热点数据

2.8.2 Redis的内存用完了会发生什么?

主要看数据淘汰策略是什么?如果是默认的配置( noeviction ),会直接报错

相关推荐
学地理的小胖砸6 分钟前
【Python 操作 MySQL 数据库】
数据库·python·mysql
呦呦鹿鸣Rzh27 分钟前
缓存的相关内容
缓存
dddaidai12332 分钟前
Redis解析
数据库·redis·缓存
数据库幼崽38 分钟前
MySQL 8.0 OCP 1Z0-908 121-130题
数据库·mysql·ocp
Amctwd1 小时前
【SQL】如何在 SQL 中统计结构化字符串的特征频率
数据库·sql
工一木子1 小时前
【Java项目脚手架系列】第七篇:Spring Boot + Redis项目脚手架
java·spring boot·redis
betazhou2 小时前
基于Linux环境实现Oracle goldengate远程抽取MySQL同步数据到MySQL
linux·数据库·mysql·oracle·ogg
lyrhhhhhhhh2 小时前
Spring 框架 JDBC 模板技术详解
java·数据库·spring
喝醉的小喵3 小时前
【mysql】并发 Insert 的死锁问题 第二弹
数据库·后端·mysql·死锁
付出不多4 小时前
Linux——mysql主从复制与读写分离
数据库·mysql