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

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


当前回答

如果您的键包含特殊字符(例如Guide$CLASSMETADATA][1]),则其他答案可能无法工作。将每个键包装成引号将确保它们被正确删除:

redis-cli --scan --pattern sf_* | awk '{print $1}' | sed "s/^/'/;s/$/'/" | xargs redis-cli del

其他回答

在bash执行:

redis-cli KEYS "prefix:*" | xargs redis-cli DEL

更新

好的,我明白了。这种方式怎么样:存储当前额外的增量前缀,并将其添加到所有的键。例如:

你的价值观是这样的:

prefix_prefix_actuall = 2
prefix:2:1 = 4
prefix:2:2 = 10

当您需要清除数据时,首先更改prefix_actuall(例如set prefix_prefix_actuall = 3),因此您的应用程序将把新数据写入关键字prefix:3:1和prefix:3:2。然后,您可以安全地从prefix:2:1和prefix:2:2中获取旧值并清除旧键。

再加上这个答案:

要找到前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_*

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

如果你有数千万或数亿个键需要匹配,这里给出的答案将导致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

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

如果你在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中有很多类型的键,比如-

“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