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

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


当前回答

这是不用任何xargs魔法就能想到的最简单的方法

纯bash !

redis-cli DEL $(redis-cli KEYS *pattern*)

其他回答

免责声明:以下解决方案不提供原子性。

从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

[1] KEYS是一个可能导致DoS的危险命令。以下摘自其文档页面:

警告:将KEYS视为只应在生产环境中极其小心地使用的命令。当它针对大型数据库执行时,可能会破坏性能。此命令用于调试和特殊操作,例如更改密钥空间布局。不要在常规应用程序代码中使用key。如果您正在寻找一种在键空间子集中查找键的方法,请考虑使用集合。

更新:一个班轮相同的基本效果-

$ redis-cli --scan --pattern "*:foo:bar:*" | xargs -L 100 redis-cli DEL

从redis 2.6.0开始,你可以运行lua脚本,它以原子方式执行。我从来没有写过,但我想应该是这样的

EVAL "return redis.call('del', unpack(redis.call('keys', ARGV[1])))" 0 prefix:[YOUR_PREFIX e.g delete_me_*]

警告:正如Redis文档所说,由于性能问题,关键字 命令不应用于生产中的常规操作,此 命令用于调试和特殊操作。读 更多的

请参阅EVAL文档。

我用EVAL命令的最简单的变体继承了这一点:

EVAL "return redis.call('del', unpack(redis.call('keys', 'my_pattern_here*')))" 0

我用我的值替换了my_pattern_here。

我也遇到了同样的问题。我为用户存储会话数据的格式为:

session:sessionid:key-x - value of x
session:sessionid:key-y - value of y
session:sessionid:key-z - value of z

因此,每个条目都是一个单独的键值对。当会话被销毁时,我想通过使用模式session:sessionid:* -删除键来删除所有会话数据,但redis没有这样的功能。

我所做的是:将会话数据存储在散列中。我只是用session:sessionid的哈希id创建了一个哈希,然后我在那个哈希中推key-x, key-y, key-z(顺序对我来说并不重要),如果我不再需要那个哈希,我只是做一个DEL session:sessionid,所有与那个哈希id相关的数据都消失了。DEL是原子的,访问数据/向哈希写入数据是O(1)。

/ /所有

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

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