Следният Lua скрипт използва SCAN
команда, така че тя изтрива на парчета в скрипта – избягвайки грешката „твърде много елементи за разопаковане“.
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 за дроселиране (вижте Има ли препоръчителна стойност на COUNT за командата SCAN / HSCAN в REDIS?). По този начин го правите на парчета вместо наведнъж, подобно на Как мога да получа всички набори в redis?
Или можете да направите нещо по-сложно, като използвате подхода, посочен в този отговор:Redis `SCAN`:как да поддържате баланс между новодошлите ключове, които могат да съвпадат и да гарантирате краен резултат в разумно време?