Poniższy skrypt Lua używa SCAN
polecenie, więc usuwa je fragmentami w skrypcie – unikając błędu „zbyt wiele elementów do rozpakowania”.
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
Zwraca ile razy SCAN
został wywołany i ile kluczy zostało usuniętych.
Użyj jako:
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
Zauważ, że zablokuje serwer podczas działania, więc nie jest zalecany do produkcji w takiej postaci, w jakiej jest.
W przypadku produkcji rozważ zmianę DEL
dla UNLINK
. Możesz również zwrócić kursor (zamiast powtarzać się w skrypcie, aż będzie zero) i dodać parametr COUNT do SCAN, aby ograniczyć (zobacz Czy jest jakaś zalecana wartość COUNT dla polecenia SCAN / HSCAN w REDIS?). W ten sposób robisz to porcjami zamiast za jednym podejściem, podobnie jak w przypadku Jak mogę uzyskać wszystkie zestawy w redis?
Lub możesz zrobić coś bardziej wyrafinowanego, korzystając z podejścia podanego w tej odpowiedzi:Redis `SCAN`:jak zachować równowagę między nowymi kluczami, które mogą pasować i zapewnić ostateczny wynik w rozsądnym czasie?