Redis
 sql >> Datenbank >  >> NoSQL >> Redis

Wie kann man Millionen von Schlüsseln, die einem Muster entsprechen, mit reinem Redis atomar löschen?

Das folgende Lua-Skript verwendet SCAN Befehl, so dass es in Blöcken innerhalb des Skripts gelöscht wird - wodurch der Fehler "zu viele Elemente zum Entpacken" vermieden wird.

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

Es gibt zurück, wie oft SCAN aufgerufen wurde und wie viele Schlüssel gelöscht wurden.

Verwenden als:

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

Beachten Sie, dass der Server während der Ausführung blockiert wird, sodass er für die Produktion so wie er ist nicht empfohlen wird.

Für die Produktion sollten Sie erwägen, DEL zu ändern für UNLINK . Sie können auch den Cursor zurückgeben (anstatt ihn innerhalb des Skripts zu wiederholen, bis er Null ist) und den COUNT-Parameter zu SCAN hinzufügen, um ihn zu drosseln (siehe Gibt es einen empfohlenen Wert von COUNT für den SCAN / HSCAN-Befehl in REDIS?). Auf diese Weise machen Sie es in Stücken statt auf einmal, ähnlich wie bei How can I get all of the sets in redis?

Oder Sie können etwas Ausgefeilteres tun, indem Sie den in dieser Antwort angegebenen Ansatz verwenden:Redis „SCAN“:Wie kann man ein Gleichgewicht zwischen neu hinzukommenden Schlüsseln aufrechterhalten, die möglicherweise übereinstimmen, und ein eventuelles Ergebnis in angemessener Zeit sicherstellen?