次のLuaスクリプトはSCAN
を使用しています コマンドなので、スクリプト内のチャンクで削除します-「解凍するには要素が多すぎます」というエラーを回避します。
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
SCAN
の回数を返します 呼び出され、削除されたキーの数。
用途:
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
実行中はサーバーをブロックするため、そのまま本番環境に移行することはお勧めしません。
本番環境では、DEL
の変更を検討してください UNLINK
の場合 。カーソルを戻し(スクリプト内でゼロになるまで繰り返すのではなく)、COUNTパラメーターをSCANに追加してスロットルすることもできます(REDISのSCAN / HSCANコマンドのCOUNTの推奨値はありますか?を参照)。この方法では、「redisですべてのセットを取得するにはどうすればよいですか?」と同様に、1回ではなくチャンクで実行します。
または、この回答に記載されているアプローチを使用して、より洗練された何かを行うことができます:Redis `SCAN`:一致する可能性のある新しいキー間のバランスを維持し、最終的な結果を妥当な時間で保証する方法は?