在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
在我的Redis DB中,我有一些前缀:<numeric_id>哈希值。
有时我想把它们都原子地清除掉。如何在不使用分布式锁定机制的情况下做到这一点呢?
当前回答
在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版本低于4,你可以试试
redis-cli -h 127.0.0.1 -p 26379 -a `yourPassword` --scan --pattern data:* | xargs redis-cli del
如果你正在使用以上4个版本,那么
redis-cli -h 127.0.0.1 -p 26379 -a `yourPassword` --scan --pattern data:*| xargs redis-cli unlink
为了检查你的版本,使用以下命令进入你的Redis终端
redis-cli -h 127.0.0.1 -p 26379 -a `yourPassword
然后输入
> INFO
# Server
redis_version:5.0.5
redis_git_sha1:00000000
redis_git_dirty:0
redis_build_id:da75abdfe06a50f8
redis_mode:standalone
os:Linux 5.3.0-51-generic x86_64
arch_bits:64
multiplexing_api:epoll
atomicvar_api:atomic-builtin
gcc_version:7.5.0
process_id:14126
run_id:adfaeec5683d7381a2a175a2111f6159b6342830
tcp_port:6379
uptime_in_seconds:16860
uptime_in_days:0
hz:10
configured_hz:10
lru_clock:15766886
executable:/tmp/redis-5.0.5/src/redis-server
config_file:
# Clients
connected_clients:22
....More Verbose
我也遇到了同样的问题。我为用户存储会话数据的格式为:
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)。
免责声明:以下解决方案不提供原子性。
从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 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);
}
}
谢谢!