在我的Redis DB中,我有许多prefix:<numeric_id>哈希值.
有时我想以原子方式清除它们.如何在不使用分布式锁定机制的情况下执行此操作?
Cas*_*sey 679
在bash中执行:
redis-cli KEYS "prefix:*" | xargs redis-cli DEL
Run Code Online (Sandbox Code Playgroud)
UPDATE
好,我明白了.这种方式:存储当前额外的增量前缀并将其添加到您的所有键.例如:
你有这样的价值观:
prefix_prefix_actuall = 2
prefix:2:1 = 4
prefix:2:2 = 10
Run Code Online (Sandbox Code Playgroud)
当您需要清除数据时,首先更改prefix_actuall(例如set prefix_prefix_actuall = 3),这样您的应用程序就会将新数据写入密钥前缀:3:1和前缀:3:2.然后,您可以安全地从前缀:2:1和前缀:2:2中取旧值并清除旧密钥.
小智 412
从redis 2.6.0开始,您可以运行以原子方式执行的lua脚本.我从未写过一篇,但我认为它看起来像这样
EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]
Run Code Online (Sandbox Code Playgroud)
请参阅EVAL文档.
Eli*_*Eli 71
这是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:
Run Code Online (Sandbox Code Playgroud)
这是@ mcdizzle在回答这个问题时的想法的工作版本.100%的想法归功于他.
编辑: Per Kikito的评论如下,如果您有更多的键要删除Redis服务器中的可用内存,您将遇到"太多要解压的元素"错误.在这种情况下,做:
for _,k in ipairs(redis.call('keys', ARGV[1])) do
redis.call('del', k)
end
Run Code Online (Sandbox Code Playgroud)
正如Kikito建议的那样.
Ita*_*ber 62
免责声明:以下解决方案不提供原子性.
从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
Run Code Online (Sandbox Code Playgroud)
[1] KEYS是一个危险的命令,可能会导致DoS.以下是其文档页面中的引用:
警告:将KEYS视为仅应在生产环境中使用的命令.在针对大型数据库执行时可能会破坏性能.此命令用于调试和特殊操作,例如更改键空间布局.不要在常规应用程序代码中使用KEYS.如果您正在寻找一种在键空间子集中查找键的方法,请考虑使用集合.
更新:一个衬垫具有相同的基本效果 -
$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL
Run Code Online (Sandbox Code Playgroud)
ran*_*mor 38
对于那些在解析其他答案时遇到问题的人:
eval "for _,k in ipairs(redis.call('keys','key:*:pattern')) do redis.call('del',k) end" 0
Run Code Online (Sandbox Code Playgroud)
替换key:*:pattern为您自己的模式,并将其输入redis-cli,你很高兴.
来自http://redis.io/commands/del的信用lisco
Yas*_*eja 34
我在redis 3.2.8中使用下面的命令
redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL
Run Code Online (Sandbox Code Playgroud)
您可以从此处获得与密钥模式搜索相关的更多帮助: - https://redis.io/commands/keys.根据您的要求使用方便的水钻样式,如*YOUR_KEY_PREFIX*或YOUR_KEY_PREFIX??或任何其他.
如果您有任何人集成了Redis PHP库,那么下面的功能将对您有所帮助.
flushRedisMultipleHashKeyUsingPattern("*YOUR_KEY_PATTERN*"); //function call
function flushRedisMultipleHashKeyUsingPattern($pattern='')
{
if($pattern==''){
return true;
}
$redisObj = $this->redis;
$getHashes = $redisObj->keys($pattern);
if(!empty($getHashes)){
$response = call_user_func_array(array(&$redisObj, 'del'), $getHashes); //setting all keys as parameter of "del" function. Using this we can achieve $redisObj->del("key1","key2);
}
}
Run Code Online (Sandbox Code Playgroud)
谢谢 :)
efa*_*ruk 19
@ mcdizle的解决方案不起作用它只适用于一个条目.
这个适用于具有相同前缀的所有密钥
EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*
Run Code Online (Sandbox Code Playgroud)
注意:您应该用您的密钥前缀替换'prefix'...
Adr*_*n B 19
我使用 EVAL 命令的最简单变体成功了这一点:
EVAL "return redis.call('del', unpack(redis.call('keys', 'my_pattern_here*')))" 0
Run Code Online (Sandbox Code Playgroud)
我my_pattern_here用我的值替换的地方。
Vis*_*kur 18
您也可以使用此命令删除密钥: -
假设您的redis中有许多类型的键,例如 -
Ex- 'xyz_category_fpc '这里xyz是一个网站名称,这些密钥与电子商务网站的产品和类别相关,并由FPC生成.
如果您使用此命令如下 -
redis-cli --scan --pattern 'key*' | xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)
要么
redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)
它会删除所有键,例如' xyz_category_fpc '(删除1,2和3键).要删除其他4,5和6个数字键,请在上面的命令中使用' xyz_product_fpc '.
如果您想在Redis中删除所有内容,请按照以下命令进行操作 -
使用redis-cli:
例如: - 在你的shell中:
redis-cli flushall
redis-cli flushdb
Run Code Online (Sandbox Code Playgroud)
Inc*_*c33 12
如果密钥名称中有空格,则可以在bash中使用:
redis-cli keys "pattern: *" | xargs -L1 -I '$' echo '"$"' | xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)
Que*_* S. 11
例如,如果您的密钥包含特殊字符,其他答案可能无效Guide$CLASSMETADATA][1]。将每个键括在引号中将确保它们被正确删除:
redis-cli --scan --pattern sf_* | awk '{print $1}' | sed "s/^/'/;s/$/'/" | xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)
小智 9
@ itamar的回答很棒,但解析回复对我不起作用,尤其是.在给定扫描中没有找到键的情况下.一个可能更简单的解决方案,直接来自控制台:
redis-cli -h HOST -p PORT --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL
Run Code Online (Sandbox Code Playgroud)
这也使用SCAN,它在生产中优于KEYS,但不是原子的.
添加到此答案:
要查找前 1000 个键:
EVAL "return redis.call('scan', 0, 'COUNT', 1000, 'MATCH', ARGV[1])" 0 find_me_*
Run Code Online (Sandbox Code Playgroud)
要删除它们:
EVAL "return redis.call('del', unpack(redis.call('SCAN', 0, 'COUNT', 1000, 'MATCH', ARGV[1])[2]))" 0 delete_me_*
Run Code Online (Sandbox Code Playgroud)
小智 9
这是在不使用任何 xargs 魔法的情况下想到的最简单的方法
纯粹的狂欢!
redis-cli DEL $(redis-cli KEYS *pattern*)
Run Code Online (Sandbox Code Playgroud)
我刚遇到同样的问题.我以下列格式存储了用户的会话数据:
session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z
Run Code Online (Sandbox Code Playgroud)
因此,每个条目都是一个单独的键值对.当会话被破坏,我想通过删除与模式键删除所有会话数据session:sessionid:*-但Redis的不具备这样的功能.
我做了什么:将会话数据存储在哈希中.我刚刚创建的散列ID的哈希值session:sessionid,然后我推key-x,key-y,key-z在哈希(顺序没有关系对我来说),如果我不需要散列了我只是做一个DEL session:sessionid与哈希ID消失了相关的所有数据.DEL是原子的并且访问数据/将数据写入散列是O(1).
小智 8
// TODO
你认为它的命令没有意义,有时 Redis 命令就像DEL无法正常工作一样,并解决了这个问题
redis-cli KEYS "*" | xargs -i redis-cli EXPIRE {} 1这是生活黑客
小智 5
我认为可能对你有帮助的是MULTI/EXEC/DISCARD.虽然不是100%等价的事务,但您应该能够将删除与其他更新隔离开来.
仅供参考.
redis-clikeys(这个用途scan)也许你只需要修改大写字符.
scan-match.sh
#!/bin/bash
rcli=“/YOUR_PATH/redis-cli"
default_server="YOUR_SERVER"
default_port="YOUR_PORT"
servers=`$rcli -h $default_server -p $default_port cluster nodes | grep master | awk '{print $2}' | sed 's/:.*//'`
if [ x"$1" == "x" ]; then
startswith="DEFAULT_PATTERN"
else
startswith="$1"
fi
MAX_BUFFER_SIZE=1000
for server in $servers; do
cursor=0
while
r=`$rcli -h $server -p $default_port scan $cursor match "$startswith*" count $MAX_BUFFER_SIZE `
cursor=`echo $r | cut -f 1 -d' '`
nf=`echo $r | awk '{print NF}'`
if [ $nf -gt 1 ]; then
for x in `echo $r | cut -f 1 -d' ' --complement`; do
echo $x
done
fi
(( cursor != 0 ))
do
:
done
done
Run Code Online (Sandbox Code Playgroud)
clear-redis-key.sh
#!/bin/bash
STARTSWITH="$1"
RCLI=YOUR_PATH/redis-cli
HOST=YOUR_HOST
PORT=6379
RCMD="$RCLI -h $HOST -p $PORT -c "
./scan-match.sh $STARTSWITH | while read -r KEY ; do
$RCMD del $KEY
done
Run Code Online (Sandbox Code Playgroud)
在bash提示符下运行
$ ./clear-redis-key.sh key_head_pattern
Run Code Online (Sandbox Code Playgroud)
使用 SCAN 而不是 KEYS(推荐用于生产服务器)--pipe而不是 xargs 的版本。
我更喜欢管道而不是 xargs,因为当您的键包含引号或您的 shell 尝试解释的其他特殊字符时,它更有效并且更有效。此示例中的正则表达式替换将键括在双引号中,并转义其中的所有双引号。
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
Run Code Online (Sandbox Code Playgroud)
请使用此命令并尝试:
redis-cli --raw keys "$PATTERN" | xargs redis-cli del
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
334187 次 |
| 最近记录: |