如何批量过期Redis中指定前缀的键?
批量为指定前缀的Redis键设置过期时间
方案一:SCAN + 管道(Pipeline)
KEYS命令在键数量较多时会阻塞Redis实例,因此推荐用SCAN分批遍历目标键,再通过管道一次性发送所有EXPIRE命令,大幅减少网络往返次数。
操作步骤
- 用
SCAN遍历前缀匹配的键:SCAN 0 MATCH hello* COUNT 10000是起始游标,每次执行后返回下一个游标,直到游标返回0表示遍历完成COUNT可根据实际键量调整,比如设为1000或更大,减少遍历轮次
- 收集键后通过管道批量执行过期设置(以Python redis-py为例):
import redis r = redis.Redis(host='localhost', port=6379, db=0) cursor = 0 expire_seconds = 3600 # 示例:设置1小时过期 while True: cursor, keys = r.scan(cursor=cursor, match='hello*', count=1000) if keys: pipe = r.pipeline() for key in keys: pipe.expire(key, expire_seconds) pipe.execute() if cursor == 0: break
方案二:Lua脚本(原子性+单次往返)
直接在Redis服务器端执行Lua脚本,一次性完成遍历和过期设置,全程仅需一次网络请求,效率最高。
执行脚本
将以下Lua脚本传入Redis执行(以redis-cli为例):
-- 自定义过期时间(单位:秒) local expire_seconds = 3600 -- 前缀参数从外部传入 local prefix = ARGV[1] local cursor = "0" repeat -- 扫描匹配前缀的键 local result = redis.call("SCAN", cursor, "MATCH", prefix.."*", "COUNT", 1000) cursor = result[1] local keys = result[2] -- 批量设置过期 for _, key in ipairs(keys) do redis.call("EXPIRE", key, expire_seconds) end until cursor == "0" return "OK"
执行命令:
redis-cli EVAL "$(cat set_expire.lua)" 0 hello
- 可根据需求修改
expire_seconds和COUNT值 - 脚本在Redis端原子执行,不会被其他命令打断
注意事项
- 禁止使用
KEYS hello*:键量巨大时,KEYS会遍历所有键,导致Redis阻塞,影响业务 - Redis集群环境下,需在每个节点单独执行SCAN或Lua脚本,因为键是分片存储的
内容的提问来源于stack exchange,提问作者Phil
相关产品推荐
相关产品推荐

