Redis

关注公众号 jb51net

关闭
首页 > 数据库 > Redis > Redis过期数据清理

Redis过期数据清理的策略实战

作者:码农技术栈

Redis中的过期键过期后不会立即从内存中删除,而是在后台进程中异步清理,如果不清理过期数据,Redis内存中的数据会越来越多,在实际应用中,Redis 的过期数据淘汰策略可以通过多种方式实现,以下是基于惰性删除和定期删除两种机制的示例代码以及最佳实践

一句话真相:Redis的过期清理就像"超市临期商品管理"——惰性删除是顾客结账时检查保质期,定期删除是店员定时巡检货架!

一、为什么需要数据过期?内存管理的生死线

真实案例:某社交App因未设过期时间,3000万用户会话数据永久堆积,导致:

Redis内存警告:

127.0.0.1:6379> info memory  
used_memory_human:6.0G   # 内存使用量  
maxmemory_human:8.0G     # 内存上限  
mem_fragmentation_ratio:1.8  # 碎片率过高!  

二、过期策略双核心:惰性删除 + 定期删除

策略触发时机优点缺点
惰性删除访问Key时检查零额外CPU消耗冷数据长期不释放
定期删除定时随机扫描主动释放内存可能短时阻塞

三、惰性删除:精准狙击的"特工"

1. 执行流程

客户端Redis过期字典GET user:1001:session检查key是否过期?已过期(返回1)删除key(nil)客户端Redis过期字典

2. 源码实现(C语言伪代码)

int expireIfNeeded(redisDb *db, robj *key) {  
    if (!keyIsExpired(db,key)) return 0;  // 未过期  
    deleteKey(db,key);                   // 执行删除  
    return 1;  
}  

robj *lookupKeyRead(redisDb *db, robj *key) {  
    if (expireIfNeeded(db,key) == 1) {   // 检查过期  
        return NULL;  // 已删除返回空  
    }  
    return lookupKey(db,key);  
}  

3. 实战风险:僵尸Key问题

场景:

# 大量已过期但永不访问的Key  
SET access_log:20230101 "big_data" EX 86400  

后果:内存被无形占用,可用空间持续减少!

四、定期删除:主动出击的"巡逻队"

1. 三层渐进式扫描

2. 核心算法参数

// redis.conf 配置  
hz 10  // 每秒执行10次定期删除(默认)  

// 源码参数  
#define ACTIVE_EXPIRE_CYCLE_KEYS_PER_LOOP 20 // 每次扫描20个key  
#define ACTIVE_EXPIRE_CYCLE_SLOW_TIME_PERC 25 // CPU占用≤25%  

3. 性能优化:自适应扫描

五、内存耗尽时的最后防线:淘汰策略

当内存超maxmemory时触发:

策略机制适用场景
volatile-lru(默认)淘汰最近最少使用的过期Key缓存场景
allkeys-lru淘汰所有Key中的LRU内存不足时优先选择
volatile-ttl淘汰剩余生存时间最短的Key时效性敏感数据
noeviction拒绝写入并报错关键数据不允许丢失

配置方式:

# redis.conf  
maxmemory 8gb  
maxmemory-policy volatile-lru  

六、四大实战陷阱与解决方案

陷阱1:过期Key集中导致雪崩

场景:

# 同一秒设置大量Key过期  
SET key1 value EX 3600  
SET key2 value EX 3600  # 同时设置100万Key  

后果:3600秒后同时过期 → 定期删除压力暴增!

解决方案:

# 添加随机过期时间偏移  
expire_time = 3600 + random.randint(0, 600)  # 增加0-10分钟随机值  
redis.setex(key, expire_time, value)  

陷阱2:大Key删除阻塞服务

案例:删除10MB的Hash Key耗时150ms → 阻塞其他请求!

优化方案:

# 异步删除(Redis 4.0+)  
UNLINK big_key  # 非阻塞删除  

# 分批次删除  
HSCAN big_key 0 COUNT 100  # 分批遍历  
HDEL big_key field1 field2 ...  # 分批删除  

陷阱3:主从不一致

问题:主库删除过期Key后,从库可能未同步删除

解决方案:

# 开启从库主动检测(Redis 3.2+)  
replica-serve-stale-data no  

陷阱4:持久化导致过期复活

原理:RDB快照中的过期Key重启后重新加载

规避方法:

# 启用AOF重写时主动删除过期Key  
aof-rewrite-incremental-fsync yes  

七、最佳配置指南

1. 生产环境推荐配置

# 内存上限(物理内存70%)  
maxmemory 16gb  

# 淘汰策略(缓存场景)  
maxmemory-policy volatile-lru  

# 定期删除频率  
hz 10  

# 开启异步删除  
lazyfree-lazy-eviction yes  

2. 监控命令大全

# 查看过期Key数量  
redis-cli info | grep expired_keys  

# 内存碎片率  
redis-cli info | grep mem_fragmentation_ratio  

# 实时监控淘汰情况  
redis-cli --stat  

八、总结:Redis过期数据清理三原则

  1. 双重保障:
    • 访问时检查(惰性删除)
    • 定时主动扫描(定期删除)
  2. 淘汰兜底:内存不足时按策略清理
  3. 避坑关键:
    • 分散过期时间
    • 大Key异步删除
    • 监控碎片率

黄金口诀:

  • 冷门数据靠定期扫
  • 热点访问惰性删
  • 内存爆炸淘汰保

以上就是Redis过期数据清理的策略实战的详细内容,更多关于Redis过期数据清理的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文