local cursor = 0
local calls = 0
local dels = 0
repeat
local result = redis.call('SCAN', cursor, 'MATCH', ARGV[1])
calls = calls + 1
for _,key in ipairs(result[2]) do
redis.call('DEL', key)
dels = dels + 1
end
cursor = tonumber(result[1])
until cursor == 0
return "Calls " .. calls .. " Dels " .. dels
它返回多少次 SCAN 以及删除了多少个键。 用作:
EVAL "local cursor = 0 local calls = 0 local dels = 0 repeat local result = redis.call('SCAN', cursor, 'MATCH', ARGV[1]) calls = calls + 1 for _,key in ipairs(result[2]) do redis.call('DEL', key) dels = dels + 1 end cursor = tonumber(result[1]) until cursor == 0 return 'Calls ' .. calls .. ' Dels ' .. dels" 0 prefix:1
注意,它将在运行时阻塞服务器,因此不建议按原样进行生产。 对于生产,考虑更改 DEL 为了 UNLINK . 您还可以返回光标(而不是在脚本中重复直到它为零),并将count参数添加到scan to throttle(请参阅redis中是否有任何建议的scan/hscan命令计数值?)。这种方法可以分块而不是一次完成,类似于我如何在redis中获得所有的集合? 或者,您可以使用这个答案中所述的方法做一些更复杂的事情:redis“scan”:如何在可能匹配的键之间保持平衡,并确保在合理的时间内最终得到结果?
2条答案
按热度按时间f2uvfpb91#
下面的lua脚本使用
SCAN
命令,因此它在脚本中分块删除—避免了“太多元素无法解包”错误。它返回多少次
SCAN
以及删除了多少个键。用作:
注意,它将在运行时阻塞服务器,因此不建议按原样进行生产。
对于生产,考虑更改
DEL
为了UNLINK
. 您还可以返回光标(而不是在脚本中重复直到它为零),并将count参数添加到scan to throttle(请参阅redis中是否有任何建议的scan/hscan命令计数值?)。这种方法可以分块而不是一次完成,类似于我如何在redis中获得所有的集合?或者,您可以使用这个答案中所述的方法做一些更复杂的事情:redis“scan”:如何在可能匹配的键之间保持平衡,并确保在合理的时间内最终得到结果?
cqoc49vn2#
lua是一个很好的选择,只要你不使用redis集群或者你想删除的所有密钥都在同一个shard上。
如果您需要从多个shard中删除密钥,您仍然可以使用lua,但是您必须发送
Eval
命令所有碎片“手动”。另一种方法是使用redisgears(redis模块),它允许您基于某些条件编写跨集群del命令。
参见示例:https://oss.redislabs.com/redisgears/examples.html#delete-按键前缀