在个人Redis数据库中,我有许多prefix:<numeric_id>
哈希。 redis
有时我想原子地清除它们。 如何在不使用某些分布式锁定机制的状况下执行此操做? 数据库
从redis 2.6.0开始,您能够运行自动执行的lua脚本。 我历来没有写过,可是我认为它看起来像这样 bash
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]
请参阅EVAL文档 。 服务器
这是在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建议的那样。 性能
穷人的原子质量删除? 网站
也许您能够将它们所有设置为在同一秒内过时(例如在将来几分钟内),而后等到那个时候看到它们同时都在“自我毁灭”。 lua
但我不肯定这将是多么原子。
对于那些在解析其余答案时遇到困难的人:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
将key:*:pattern
替换为您本身的模式,而后将其输入redis-cli
,您就能够开始了。
来自如下网站的信用口岸: http ://redis.io/commands/del
免责声明:如下解决方案不提供原子性。
从v2.8开始,您确实要使用SCAN命令而不是KEYS [1]。 如下Bash脚本演示了按模式删除密钥:
#!/bin/bash if [ $# -ne 3 ] then echo "Delete keys from Redis matching a pattern using SCAN & DEL" echo "Usage: $0 <host> <port> <pattern>" exit 1 fi cursor=-1 keys="" while [ $cursor -ne 0 ]; do if [ $cursor -eq -1 ] then cursor=0 fi reply=`redis-cli -h $1 -p $2 SCAN $cursor MATCH $3` cursor=`expr "$reply" : '\([0-9]*[0-9 ]\)'` keys=${reply##[0-9]*[0-9 ]} redis-cli -h $1 -p $2 DEL $keys done
[1] KEYS是一种危险的命令,有可能致使DoS。 如下是其文档页面的引文:
警告:将KEYS视为命令,仅应格外当心地用于生产环境。 在大型数据库上执行时,可能会破坏性能。 此命令用于调试和特殊操做,例如更改键空间布局。 不要在常规应用程序代码中使用KEYS。 若是您正在寻找一种在键空间的子集中查找键的方法,请考虑使用集合。
更新:具备相同基本效果的一根衬板-
$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL