El siguiente script de Lua usa SCAN
comando, por lo que se elimina en fragmentos dentro de la secuencia de comandos, evitando el error "demasiados elementos para desempaquetar".
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
Devuelve cuantas veces SCAN
fue llamado y cuántas claves se eliminaron.
Usar como:
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
Tenga en cuenta que bloqueará el servidor mientras se ejecuta, por lo que no se recomienda para la producción tal cual.
Para producción, considere cambiar DEL
para UNLINK
. También puede devolver el cursor (en lugar de repetirlo dentro de la secuencia de comandos hasta que sea cero) y agregar el parámetro COUNT a SCAN para acelerar (consulte ¿Hay algún valor recomendado de COUNT para el comando SCAN / HSCAN en REDIS?). De esta manera, lo hace en partes en lugar de una sola vez, similar a ¿Cómo puedo obtener todos los conjuntos en redis?
O puede hacer algo más sofisticado utilizando el enfoque indicado en esta respuesta:Redis `SCAN`:¿cómo mantener un equilibrio entre las claves recién llegadas que podrían coincidir y garantizar un resultado final en un tiempo razonable?