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

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


当前回答

/ /所有

你认为这是没有意义的命令,但有时Redis命令像DEL不能正确工作,来拯救这个

redis-cli KEYS "*" | xargs -i redis-cli EXPIRE {} 1 it's life hack

其他回答

现在,您可以使用redis客户端并执行第一次扫描(支持模式匹配),然后单独DEL每个键。

然而,在官方redis github上有一个问题,在这里创建一个模式匹配-del,如果你发现它有用,就去展示它吧!

@itamar的回答很棒,但对回复的解析对我来说并不管用,特别是在给定扫描中没有找到键的情况下。一个可能更简单的解决方案,直接从控制台:

redis-cli -h HOST -p PORT  --scan --pattern "prefix:*" | xargs -n 100 redis-cli DEL

这也使用了SCAN,它在生产中比KEYS更可取,但不是原子的。

这并不是对这个问题的直接回答,但因为我是在寻找自己的答案时来到这里的,所以我将在这里分享。

如果你有数千万或数亿个键需要匹配,这里给出的答案将导致Redis在很长一段时间内(几分钟?)没有响应,并可能因为内存消耗而崩溃(当然,后台保存将在你的操作过程中启动)。

下面的方法不可否认是丑陋的,但我没有找到更好的方法。原子性在这里是没有问题的,在这种情况下,主要目标是保持Redis的正常运行和100%的响应。如果您将所有的密钥都放在一个数据库中,并且不需要匹配任何模式,那么它将完美地工作,但不能使用http://redis.io/commands/FLUSHDB,因为它具有阻塞特性。

想法很简单:写一个脚本,在循环中运行,使用O(1)操作,如http://redis.io/commands/SCAN或http://redis.io/commands/RANDOMKEY来获取密钥,检查它们是否匹配模式(如果你需要的话),然后逐个http://redis.io/commands/DEL它们。

如果有更好的方法,请告诉我,我会更新答案。

Ruby中使用randomkey的示例实现,作为rake任务,以非阻塞方式代替redis-cli -n 3 flushdb:

desc 'Cleanup redis'
task cleanup_redis: :environment do
  redis = Redis.new(...) # connection to target database number which needs to be wiped out
  counter = 0
  while key = redis.randomkey               
    puts "Deleting #{counter}: #{key}"
    redis.del(key)
    counter += 1
  end
end

@mcdizle的解决方案是行不通的,它只适用于一个条目。

这一项适用于具有相同前缀的所有键

EVAL "for i, name in ipairs(redis.call('KEYS', ARGV[1])) do redis.call('DEL', name); end" 0 prefix*

注意:你应该用你的密钥前缀替换'prefix'…

我在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);
            }
        }

谢谢!