当前位置:首页 > 问答 > 正文

Redis缓存 定期清理主从Redis缓存实现方案,主从redis缓存定时清理方法

Redis缓存清理实战:主从架构定时清理方案详解

场景引入:当缓存成为"垃圾场"

想象一下这个场景:你的电商平台正在经历促销活动,Redis缓存中堆积了大量临时商品数据和用户会话信息,活动结束后,这些数据就像派对结束后散落一地的彩带和气球,不仅占用宝贵的内存空间,还可能因为过期数据导致业务逻辑出错,更糟的是,你的Redis采用主从架构,手动清理既繁琐又容易出错...

这就是为什么我们需要一套自动化、可靠的Redis主从缓存清理方案,下面我将详细介绍几种实用方法,帮你解决这个运维痛点。

基础方案:Redis自带过期策略

1 被动过期(惰性删除)

# 设置键的过期时间(单位:秒)
127.0.0.1:6379> SET coupon:user123 "50%OFF" EX 86400

特点

  • 访问键时检查是否过期,过期则删除
  • 优点:CPU友好,只在访问时消耗资源
  • 缺点:可能导致大量已过期但未被访问的键堆积

2 主动过期(定期删除)

Redis默认每10秒随机检查20个键,发现过期立即删除

Redis缓存 定期清理主从Redis缓存实现方案,主从redis缓存定时清理方法

配置调整(redis.conf):

# 调整主动删除频率(默认10hz即每秒10次)
hz 20
# 每次扫描的键数量(默认20)
active-expire-effort 50

适用场景

  • 适合过期键分布均匀的中小型系统
  • 主从架构下会自动同步过期操作

进阶方案:定时任务批量清理

1 Redis-CLI脚本方案

#!/bin/bash
# 清理匹配特定模式的键(主节点执行)
REDIS_MASTER="127.0.0.1"
PORT=6379
PASSWORD="yourpassword"
PATTERN="temp:*"
# 使用SCAN避免阻塞(生产环境建议在低峰期执行)
redis-cli -h $REDIS_MASTER -p $PORT -a $PASSWORD --scan --pattern "$PATTERN" | \
xargs -L 100 redis-cli -h $REDIS_MASTER -p $PORT -a $PASSWORD del

注意事项

  1. 大Key删除可能引起短暂阻塞
  2. 建议分批执行,每次删除不超过1000个键
  3. 从节点会自动同步删除操作

2 Lua脚本原子化执行

-- cleanup.lua
local pattern = KEYS[1]
local batchSize = tonumber(ARGV[1])
local cursor = "0"
local deleted = 0
repeat
    local reply = redis.call("SCAN", cursor, "MATCH", pattern, "COUNT", batchSize)
    cursor = reply[1]
    local keys = reply[2]
    if #keys > 0 then
        redis.call("DEL", unpack(keys))
        deleted = deleted + #keys
    end
until cursor == "0"
return deleted

执行命令:

Redis缓存 定期清理主从Redis缓存实现方案,主从redis缓存定时清理方法

redis-cli -h master_host --eval cleanup.lua "session:*" , 500

企业级方案:主从安全清理策略

1 双阶段清理方案

  1. 标记阶段(低峰期执行):

    # 为待清理键添加标记
    redis-cli --scan --pattern "cache:*" | xargs -L 100 redis-cli EXPIRE 3600
  2. 删除阶段(次日执行):

    # 清理前一天标记的键
    redis-cli SCAN 0 MATCH "cache:*" COUNT 1000 | \
    awk '{print "redis-cli TTL "$1}' | \
    grep "^-1$" | \
    awk '{print "redis-cli DEL "$1}'

2 主从切换清理法

import redis
def safe_clean_slave(master_host, slave_host, pattern):
    # 步骤1:提升从节点为临时主节点
    slave = redis.Redis(host=slave_host)
    slave.config_set('slaveof', 'no', 'one')
    # 步骤2:在新主节点执行清理
    keys_deleted = 0
    cursor = '0'
    while cursor != 0:
        cursor, keys = slave.scan(cursor=cursor, match=pattern, count=1000)
        if keys:
            slave.delete(*keys)
            keys_deleted += len(keys)
    # 步骤3:恢复主从关系
    slave.config_set('slaveof', master_host, '6379')
    return keys_deleted

监控与优化建议

1 清理前检查清单

  1. 确认主从同步状态:
    redis-cli info replication
  2. 检查内存碎片率:
    redis-cli info memory | grep ratio
  3. 预估删除影响:
    redis-cli --scan --pattern "temp:*" | wc -l

2 性能优化技巧

  • 时间选择:在业务低峰期(如凌晨2-4点)执行批量清理
  • 分批处理:每次清理不超过总键数的5%
  • 内存回收:清理后执行MEMORY PURGE(Redis 4.0+)
  • 监控告警:设置used_memoryevicted_keys监控项

特殊场景处理

1 集群模式下的清理

# 遍历所有主节点执行清理
for node in $(redis-cli cluster nodes | grep master | awk '{print $2}' | cut -d@ -f1); do
    redis-cli -h ${node%:*} -p ${node#*:} --scan --pattern "temp:*" | \
    xargs -L 100 redis-cli -h ${node%:*} -p ${node#*:} del
done

2 大Key专项清理

# 查找大于1MB的Key
redis-cli --bigkeys
# 渐进式删除大Hash
redis-cli hscan big_hash 0 | \
awk '{if(NR>1){print $0}}' | \
xargs -L 2 | \
awk '{print "redis-cli hdel big_hash "$1}'

选择合适的Redis清理方案就像选择打扫工具——小范围用"鸡毛掸子"(惰性删除),日常维护用"扫地机器人"(定期删除),大扫除就得用"高压水枪"(批量清理),主从架构下切记:所有写操作必须通过主节点,从节点会自动同步。

根据2025年最新的Redis最佳实践,建议组合使用:

Redis缓存 定期清理主从Redis缓存实现方案,主从redis缓存定时清理方法

  1. 合理设置TTL实现自动过期
  2. 每周低峰期执行模式匹配清理
  3. 每月深度清理+内存碎片整理

没有放之四海皆准的方案,关键是根据业务特点找到平衡点——既不让缓存变成垃圾场,也不因过度清理导致缓存穿透。

发表评论