在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
当前回答
如果您的键包含特殊字符(例如Guide$CLASSMETADATA][1]),则其他答案可能无法工作。将每个键包装成引号将确保它们被正确删除:
redis-cli --scan --pattern sf_* | awk '{print $1}' | sed "s/^/'/;s/$/'/" | xargs redis-cli del
其他回答
对于那些无法解析其他答案的人:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
将key:*:pattern替换为您自己的模式,并将其输入到redis-cli中,就可以开始了。
Credit lisco来自:http://redis.io/commands/del
现在,您可以使用redis客户端并执行第一次扫描(支持模式匹配),然后单独DEL每个键。
然而,在官方redis github上有一个问题,在这里创建一个模式匹配-del,如果你发现它有用,就去展示它吧!
使用SCAN而不是KEYS(推荐用于生产服务器)和——pipe而不是xargs的版本。
与xargs相比,我更喜欢pipe,因为它更有效,并且在键包含引号或shell尝试和解释的其他特殊字符时也能工作。本例中的regex替换用双引号包装键,并转义其中的任何双引号。
export REDIS_HOST=your.hostname.com
redis-cli -h "$REDIS_HOST" --scan --pattern "YourPattern*" > /tmp/keys
time cat /tmp/keys | perl -pe 's/"/\\"/g;s/^/DEL "/;s/$/"/;' | redis-cli -h "$REDIS_HOST" --pipe
下面是一个用Lua实现的通配符删除的完整的原子版本。它将比xargs版本运行得快得多,因为它的网络来回更少,而且它完全是原子的,可以阻止任何其他针对redis的请求,直到它完成。如果你想在Redis 2.6.0或更高版本上自动删除键,这绝对是正确的方法:
redis-cli -n [some_db] -h [some_host_name] EVAL "return redis.call('DEL', unpack(redis.call('KEYS', ARGV[1] .. '*')))" 0 prefix:
这是@mcdizzle对这个问题的回答中的一个有效版本。这主意100%归他。
编辑:根据Kikito下面的评论,如果你要删除的键比Redis服务器的空闲内存多,你会遇到“太多元素要解包”错误。在这种情况下,请:
for _,k in ipairs(redis.call('keys', ARGV[1])) do
redis.call('del', k)
end
正如Kikito所建议的。
从redis 2.6.0开始,你可以运行lua脚本,它以原子方式执行。我从来没有写过,但我想应该是这样的
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]
警告:正如Redis文档所说,由于性能问题,关键字 命令不应用于生产中的常规操作,此 命令用于调试和特殊操作。读 更多的
请参阅EVAL文档。