redis存储了很多无用的key,占用了大量内存,需要清除
第一种 (颗粒度较大)
lua脚本,删除某些规则的key,输入删除的key,返回删除的符合规则的key的数量
弊端:颗粒度比较大,发送一个lua脚本去执行,会占用较多时间,堵塞其他redis命令
local function scan(key)
local cursor = 0
local keynum = 0
repeat
local res = redis.call("scan", cursor, "match", key, "COUNT", ARGV[1])
if(res ~= nil and #res >= 0) then
redis.replicate_commands()
cursor = tonumber(res[1])
local ks = res[2]
local keynum1 = #ks
keynum = keynum + keynum1
for i=1,keynum1,1 do
local k = tostring(ks[i])
redis.call("del", k)
end
end
until(cursor <= 0)
return keynum
end
local a = #KEYS
local b = 1
local total = 0
while(b <= a)
do
total = total + scan(KEYS[b])
b=b+1
end
return total
java代码
String delLua = "local function scan(key)\n" +
"\tlocal cursor = 0\n" +
"\tlocal keynum = 0\n" +
"\trepeat\n" +
"\t\tlocal res = redis.call(\"scan\", cursor, \"match\", key, \"COUNT\", ARGV[1])\n" +
"\t\tif(res ~= nil and #res >= 0) then\n" +
"\t\t\tredis.replicate_commands()\n" +
"\t\t\tcursor = tonumber(res[1])\n" +
"\t\t\tlocal ks = res[2]\n" +
"\t\t\tlocal keynum1 = #ks\n" +
"\t\t\tkeynum = keynum + keynum1\n" +
"\t\t\tfor i=1,keynum1,1 do\n" +
"\t\t\t\tlocal k = tostring(ks[i])\n" +
"\t\t\t\tredis.call(\"del\", k)\n" +
"\t\t\tend\n" +
"\t\tend\n" +
"\tuntil(cursor <= 0)\n" +
"\treturn keynum\n" +
"end\n" +
"\n" +
"local a = #KEYS\n" +
"local b = 1 \n" +
"local total = 0\n" +
"while(b <= a)\n" +
"do \n" +
"\ttotal = total + scan(KEYS[b])\n" +
"\tb=b+1\n" +
"end\n" +
"\n" +
"return total";
// 指定 lua 脚本,并且指定返回值类型
DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>(delLua, Long.class);
// 参数一:redisScript,参数二:key列表,参数三:arg(可多个)
long start = System.currentTimeMillis();
Long result = (Long) redisTemplate.execute(redisScript, Collections.singletonList(scenicId + ":*"), 20000);
long end = System.currentTimeMillis();
这样直接删除,因为规则有很多个,需要循环删除,每一次调用脚本都需要占用redis一分多时间,文章来源:https://www.toymoban.com/news/detail-861151.html
第二种(切割所有key,每次返回指定数量,然后过滤删除)
lua脚本文章来源地址https://www.toymoban.com/news/detail-861151.html
local cursor = ARGV[1]
local result = redis.call('SCAN', cursor, 'COUNT', 10000)
return {result[1], result[2]}
// Lua脚本用于SCAN操作,获取指定数量的key
String luaScript = "local cursor = ARGV[1]\n" +
"local result = redis.call('SCAN', cursor, 'COUNT', 10000)\n" +
"return {result[1], result[2]}";
// 创建Redis脚本对象
DefaultRedisScript<List> defaultRedisScript = new DefaultRedisScript<>(luaScript, List.class);
defaultRedisScript.setResultType(List.class);
Integer cursorInt = 0;
String newCursor = cursorInt.toString(); // 初始游标
// 参数:cursor初始为0,match为""表示匹配所有key,count为1000
List<Object> keys = stringRedisTemplate.execute(defaultRedisScript, Collections.emptyList(), newCursor);
// 解析结果
newCursor = keys.get(0).toString(); // 新的cursor
List<String> keyList = (List<String>)keys.get(1);
//对获取出来的key进行规则筛选,查看那些可以直接删除
//过滤逻辑 和 删除
到了这里,关于redis 无占用 两种方式 清除大批量数据 lua脚本的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!