场景介绍
批量删除redis中指定前缀的key;
redis版本
本文介绍方法在redis-6.2.1版本中测试通过;
删除指定前缀的key
由于在实际项目的复杂性,需要批量删除的数据中有些是无效的,有些可能还未处理(比如秒杀业务中缓存中生成的订单还未同步到数据库中),所以此处是以“设置过期时间的方式,达到删除数据的目的”,这种方式能够让将要被删除的数据有充分的时间被处理。
连接redis然后执行如下命令
EVAL "local cursor = '0' local pattern = ARGV[1] local minExpire = tonumber(ARGV[2]) local maxExpire = tonumber(ARGV[3]) repeat local result = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', 500) cursor = result[1] local keys = result[2] for i, key in ipairs(keys) do local randomExpire = math.random(minExpire, maxExpire) redis.call('EXPIRE', key, randomExpire) end until cursor == '0'" 0 abc* 7200 7800
这段代码是一个 Lua 脚本,用于在 Redis 数据库中扫描指定模式的键,并为匹配的键设置随机过期时间。
代码中的参数解释如下:
- local cursor = '0' :
定义初始游标为0,用于迭代扫描操作。
- local pattern = ARGV[1] :
获取第一个传入参数作为键的模式匹配规则。
- local minExpire = tonumber(ARGV[2]) :
获取第二个传入参数作为最小过期时间,使用tonumber函数将其转化为数字类型。
- local maxExpire = tonumber(ARGV[3]) :
获取第三个传入参数作为最大过期时间,同样使用tonumber函数进行转化。
- repeat :
开始一个重复循环,直到游标为0时结束。
- local result = redis.call('SCAN', cursor, 'MATCH', pattern, 'COUNT', 500) :
使用 Redis的SCAN命令扫描匹配模式的键,每次扫描500个键。
- cursor = result[1] :
更新游标为扫描结果中的游标,用于下一次迭代。
- local keys = result[2] :
获取扫描结果中的键列表。
- for i, key in ipairs(keys) do :
遍历键列表。
- local randomExpire = math.random(minExpire, maxExpire) :
生成一个随机的过期时间,介于最小过期时间和最大过期时间之间。
- redis.call('EXPIRE', key, randomExpire) :
使用 Redis的EXPIRE命令为键设置过期时间。
- until cursor == '0' :
循环条件,当游标为0时结束循环。
这段代码的作用是将固定前缀为“abc”的键设置为2个小时到2个半小时之间的随机过期时间即传入的最小和最大值之间。
注意
实际测试过程中,删除了大概200万条数据,耗时5秒(4核16G服务器),删除过程中会有部分redis请求超时,线上业务尽量避开业务高峰期执行。
附:redis批量写入统一前缀的key
上述方法尽量先从测试环境中模拟线上环境进行测试,测试时如果需要生成大量缓存数据可参考如下方法:
使用redis命令批量写入200万数据 统一的key前缀+随机数,value都为111
要使用Redis命令批量写入200万数据,可以使用以下脚本:
script.lua
math.randomseed(1234) -- 设置随机种子,确保生成的随机数一致
for i=1, 2000000 do
local key = "abc" .. tostring(math.random(10000000))
redis.call("SET", key, "111")
end
执行命令:
brredis-cli --eval script.lua
在这个脚本中,我们使用Lua脚本生成了200万个随机的key,并将其与统一的前缀拼接。然后,我们使用Redis的SET命令将每个key的值设置为"111"。你可以根据需要修改前缀和值的内容。