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 ),会直接报错

相关推荐
敖云岚38 分钟前
【Redis】分布式锁的介绍与演进之路
数据库·redis·分布式
LUCIAZZZ1 小时前
HikariCP数据库连接池原理解析
java·jvm·数据库·spring·springboot·线程池·连接池
我在北京coding1 小时前
300道GaussDB(WMS)题目及答案。
数据库·gaussdb
小Tomkk2 小时前
阿里云 RDS mysql 5.7 怎么 添加白名单 并链接数据库
数据库·mysql·阿里云
明月醉窗台2 小时前
qt使用笔记二:main.cpp详解
数据库·笔记·qt
让我上个超影吧3 小时前
黑马点评【基于redis实现共享session登录】
java·redis
沉到海底去吧Go3 小时前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名
老纪的技术唠嗑局3 小时前
重剑无锋,大巧不工 —— OceanBase 中的 Nest Loop Join 使用技巧分享
数据库·sql
未来之窗软件服务4 小时前
JAVASCRIPT 前端数据库-V6--仙盟数据库架构-—-—仙盟创梦IDE
数据库·数据库架构·仙盟创梦ide·东方仙盟·东方仙盟数据库
一只爱撸猫的程序猿5 小时前
构建一个简单的智能文档问答系统实例
数据库·spring boot·aigc