在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。

有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?


当前回答

我在redis 3.2.8中使用以下命令

redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL

您可以从这里获得更多有关键模式搜索的帮助:- 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);
            }
        }

谢谢!

其他回答

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

我尝试了上面提到的大部分方法,但对我来说都不奏效,经过一些搜索,我发现了以下几点:

如果你在redis上有多个数据库,你应该使用-n [number]来确定数据库。 如果你有几个键使用del,但如果有成千上万或数百万个键,最好使用unlink,因为unlink是非阻塞的,而del是阻塞的,更多信息请访问这个页面unlink vs del 键也像del和is blocking

所以我用这段代码按模式删除键:

 redis-cli -n 2 --scan --pattern '[your pattern]' | xargs redis-cli -n 2 unlink 

下面的命令对我很有用。

redis-cli -h redis_host_url KEYS "*abcd*" | xargs redis-cli -h redis_host_url DEL

您还可以使用该命令删除密钥

假设你的redis中有很多类型的键,比如-

“xyz_category_fpc_12” “xyz_category_fpc_245” “xyz_category_fpc_321” “xyz_product_fpc_876” “xyz_product_fpc_302” “xyz_product_fpc_01232”

Ex- 'xyz_category_fpc'这里xyz是一个站点名称,这些键与电子商务网站的产品和类别相关,由FPC生成。

如果您像下面那样使用此命令-

redis-cli --scan --pattern 'key*' | xargs redis-cli del

OR

redis-cli --scan --pattern 'xyz_category_fpc*' | xargs redis-cli del

它删除所有的键,如“xyz_category_fpc”(删除1、2和3个键)。若要删除其他4,5和6数字键,请使用上述命令中的'xyz_product_fpc'。

如果你想删除所有在Redis,然后按照这些命令-

redis-cli:

FLUSHDB -从连接的当前数据库中删除数据。 FLUSHALL—从所有数据库中删除数据。

例如:-在你的壳:

redis-cli flushall
redis-cli flushdb

再加上这个答案:

要找到前1000个键:

EVAL "return redis.call('scan', 0, 'COUNT', 1000, 'MATCH', ARGV[1])" 0 find_me_*

删除它们:

EVAL "return redis.call('del', unpack(redis.call('SCAN', 0, 'COUNT', 1000, 'MATCH', ARGV[1])[2]))" 0 delete_me_*