Redis
 sql >> Base de données >  >> NoSQL >> Redis

Comment supprimer atomiquement des millions de clés correspondant à un modèle à l'aide de Redis pur ?

Le script Lua suivant utilise SCAN commande, de sorte qu'il supprime en morceaux dans le script - en évitant l'erreur "trop ​​d'éléments à décompresser".

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

Il renvoie combien de fois SCAN a été appelé et combien de clés ont été supprimées.

Utiliser comme :

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

Notez que cela bloquera le serveur lors de son exécution, il n'est donc pas conseillé pour la production telle quelle.

Pour la production, pensez à modifier DEL pour UNLINK . Vous pouvez également renvoyer le curseur (au lieu de répéter à l'intérieur du script jusqu'à ce qu'il soit à zéro) et ajouter le paramètre COUNT à SCAN pour accélérer (voir Existe-t-il une valeur recommandée de COUNT pour la commande SCAN / HSCAN dans REDIS ?). De cette façon, vous le faites en plusieurs morceaux au lieu d'une seule fois, comme dans Comment puis-je obtenir tous les ensembles dans redis ?

Ou vous pouvez faire quelque chose de plus sophistiqué en utilisant l'approche indiquée dans cette réponse :Redis `SCAN` :comment maintenir un équilibre entre les nouvelles clés entrantes qui pourraient correspondre et garantir un résultat final dans un délai raisonnable ?