Redis
 sql >> Database >  >> NoSQL >> Redis

Come eliminare atomicamente milioni di chiavi corrispondenti a un modello usando Redis puro?

Il seguente script Lua utilizza SCAN comando, quindi elimina in blocchi all'interno dello script, evitando l'errore "troppi elementi da decomprimere".

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

Restituisce quante volte SCAN è stato chiamato e quante chiavi sono state cancellate.

Usa come:

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

Nota che bloccherà il server durante l'esecuzione, quindi non è consigliato per la produzione così com'è.

Per la produzione, valuta la possibilità di modificare DEL per UNLINK . Puoi anche restituire il cursore (invece di ripetere all'interno dello script fino a quando non è zero) e aggiungere il parametro COUNT a SCAN per accelerare (vedi C'è un valore consigliato di COUNT per il comando SCAN / HSCAN in REDIS?). In questo modo lo fai in blocchi anziché in una volta, simile a Come posso ottenere tutti i set in redis?

Oppure puoi fare qualcosa di più sofisticato usando l'approccio indicato in questa risposta:Redis `SCAN`:come mantenere un equilibrio tra le chiavi di nuova immissione che potrebbero corrispondere e garantire il risultato finale in un tempo ragionevole?