在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
当前回答
如果你使用windows环境,请遵循以下步骤,它一定会工作:
Download GOW from here - https://github.com/bmatzelle/gow/wiki (because xargs command doesn't works in windows) Download redis-cli for Windows (detailed explanation is here - https://medium.com/@binary10111010/redis-cli-installation-on-windows-684fb6b6ac6b) Run cmd and open directory where redis-cli stores (example: D:\Redis\Redis-x64-3.2.100) if you want to delete all keys which start with "Global:ProviderInfo" execute this query (it's require to change bold parameters (host, port, password, key) and write yours, because of this is only example): redis-cli -h redis.test.com -p 6379 -a redispassword --raw keys "Global:ProviderInfo*" | xargs redis-cli -h redis.test.com -p 6379 -a redispassword del
其他回答
我想可能对你有帮助的是MULTI/EXEC/DISCARD。虽然不是100%等同于事务,但您应该能够将删除与其他更新隔离开来。
请使用此命令并尝试:
redis-cli --raw keys "$PATTERN" | xargs redis-cli del
FYI.
只使用bash和redis-cli 不使用键(这使用扫描) 在集群模式下工作良好 不是原子
也许您只需要修改大写字符。
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
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
在bash提示符下运行
$ ./clear-redis-key.sh key_head_pattern
如果我们想要确保原子操作,我们可以尝试编写一个Lua脚本。
如果你的Redis版本支持SCAN和UNLINK(高于4.0.0),我更喜欢在生产环境中使用SCAN和UNLINK而不是Key和DEL,因为Key和DEL命令可能会阻塞
它们可以在生产环境中使用,而没有KEYS或members等命令的缺点,这些命令在针对大量键或元素集合调用时可能会阻塞服务器很长时间(甚至几秒钟)。
EVAL "local cursor = 0 repeat local result = redis.call('SCAN', cursor, 'MATCH', ARGV[1]) for _,key in ipairs(result[2]) do redis.call('UNLINK', key) end cursor = tonumber(result[1]) until cursor == 0 " 0 prefix:*
我们可以随意更改前缀:*。
@mcdizle的解决方案是行不通的,它只适用于一个条目。
这一项适用于具有相同前缀的所有键
EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*
注意:你应该用你的密钥前缀替换'prefix'…