sql >> Base de Datos >  >> NoSQL >> Redis

¿Cómo eliminar atómicamente millones de claves que coinciden con un patrón usando Redis puro?

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?