EDIT: Per Kikito 's comment below, if you have more keys to delete than free memory in your Redis server, you' ll遇到"too many elements to unpack" error . 在这种情况下,做:
for _,k in ipairs(redis.call('keys', ARGV[1])) do
redis.call('del', k)
end
正如Kikito建议的那样 .
15
我在redis 3.2.8中使用下面的命令
redis-cli KEYS *YOUR_KEY_PREFIX* | xargs redis-cli DEL
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);
}
}
谢谢 :)
31
仅供参考 .
仅使用bash和 redis-cli
不使用 keys (这使用 scan )
在 cluster mode 运作良好
not atomic
也许你只需要修改大写字符 .
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
68
redis-cli keys "*prefix*" 为我工作
-1
You can also use this command to delete the keys:-
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
21 回答
在bash中执行:
UPDATE
好,我明白了 . 这种方式:存储当前额外的增量前缀并将其添加到您的所有键 . 例如:
你有这样的 Value 观:
当您需要清除数据时,首先更改prefix_actuall(例如set prefix_prefix_actuall = 3),这样您的应用程序就会将新数据写入密钥前缀:3:1和前缀:3:2 . 然后,您可以安全地从前缀:2:1和前缀:2:2中取旧值并清除旧密钥 .
它很容易通过FastoRedis中的"Remove branch"功能实现,只需选择要删除的分支 .
穷人的原子质量删除?
也许你可以将它们全部设置为EXPIREAT相同的秒 - 比如将来的几分钟 - 然后等到那个时候,看到它们同时“自我毁灭” .
但我不确定那将是多么原子 .
我刚遇到同样的问题 . 我以下列格式存储了用户的会话数据:
因此,每个条目都是一个单独的键值对 . 当会话被销毁时,我想通过删除模式为
session:sessionid:*
的键来删除所有会话数据 - 但是redis没有这样的功能 .我做了什么:将会话数据存储在hash中 . 我只是创建一个哈希id为
session:sessionid
的哈希,然后我在那个哈希中推送key-x
,key-y
,key-z
(顺序对我来说无关紧要)如果我不再需要那个哈希,我只需要做DEL session:sessionid
以及与之关联的所有数据哈希id消失了 .DEL
是原子的,访问数据/写入哈希的数据是O(1) .从redis 2.6.0开始,您可以运行原子执行的lua脚本 . 我从来没有写过,但我觉得它看起来像这样
见EVAL documentation .
请使用此命令并尝试:
我认为可能对你有帮助的是MULTI/EXEC/DISCARD . 虽然不是100% equivalent of transactions,但您应该能够将删除与其他更新隔离开来 .
免责声明:以下解决方案 doesn't 提供原子性 .
从v2.8开始, really 想要使用SCAN命令而不是KEYS [1] . 以下Bash脚本演示了按模式删除键:
[1] KEYS是一个危险的命令,可能会导致DoS . 以下是其文档页面中的引用:
UPDATE: 一个衬垫具有相同的基本效果 -
对于那些在解析其他答案时遇到问题的人:
用您自己的模式替换
key:*:pattern
并将其输入redis-cli
并且您很高兴 .来自的信用点评:http://redis.io/commands/del
这是Lua中实现的通配符删除的完全工作和原子版本 . 它的运行速度比xargs版本要快得多,因为它来回的网络要少得多,而且完全是原子的,阻止任何其他的redis请求,直到完成为止 . 如果你想以原子方式删除Redis 2.6.0或更高版本上的密钥,这绝对是要走的路:
这是@ mcdizzle在回答这个问题时的想法的工作版本 . 100%的想法归功于他 .
EDIT: Per Kikito 's comment below, if you have more keys to delete than free memory in your Redis server, you' ll遇到"too many elements to unpack" error . 在这种情况下,做:
正如Kikito建议的那样 .
我在redis 3.2.8中使用下面的命令
您可以从此处获得与键模式搜索相关的更多帮助: - https://redis.io/commands/keys . 根据您的要求使用方便的glob样式模式,如 YOUR_KEY_PREFIX 或 YOUR_KEY_PREFIX?? 或任何其他 .
如果你们中的任何人已经集成 Redis PHP library 而不是以下功能将帮助你 .
谢谢 :)
仅供参考 .
仅使用bash和
redis-cli
不使用
keys
(这使用scan
)在 cluster mode 运作良好
not atomic
也许你只需要修改大写字符 .
scan-match.sh
clear-redis-key.sh
在bash提示符下运行
redis-cli keys "*prefix*"
为我工作You can also use this command to delete the keys:-
假设您的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 是 sitename ,这些密钥与电子商务网站的产品和类别相关,并由FPC生成 .
如果您使用以下命令 -
要么
它删除所有键,如' xyz_category_fpc ' (delete 1, 2 and 3 keys). For delete other 4, 5 and 6 number keys use ' xyz_product_fpc '在上面的命令中 .
如果你想在 Redis 中 Delete Everything ,那么按照这些命令 -
With redis-cli:
FLUSHDB - 从连接的CURRENT数据库中删除数据 .
FLUSHALL - 从所有数据库中删除数据 .
例如: - 在你的shell中:
@ itamar的回答很棒,但是回复的解析对我来说不起作用,尤其是 . 在给定扫描中没有找到键的情况下 . 一个可能更简单的解决方案,直接来自控制台:
这也使用SCAN,它在 生产环境 中优于KEYS,但不是原子的 .
这不是问题的直接答案,但由于我在搜索自己的答案时到了这里,我将在这里分享 .
如果你必须匹配数十或数亿个密钥,这里给出的答案将导致Redis在很长时间内没有响应(几分钟?),并且可能因内存消耗而崩溃(确保后台保存将会在你的操作过程中开始) .
以下方法无疑是丑陋的,但我没有需要匹配任何模式,但由于它的阻塞性质,不能使用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
这样的非阻塞替代:使用SCAN而不是KEYS(对于 生产环境 服务器推荐)和
--pipe
而不是xargs的版本 .我更喜欢管道覆盖xargs,因为它更高效,并且当你的密钥包含引号或其他特殊字符时,你的shell可以尝试和解释 . 此示例中的正则表达式替换将键包装在双引号中,并转义内部的任何双引号 .
我支持所有与使用某个工具或执行Lua表达式相关的答案 .
我方还有一个选择:
在我们的 生产环境 和预 生产环境 数据库中,有数千个密钥 . 我们需要不时删除一些键(通过某些掩码),按某些标准修改等等 . 当然,没有办法从CLI手动完成,特别是有分片(每个物理中有512个逻辑dbs) .
为此我编写了java客户端工具来完成所有这些工作 . 如果删除密钥,实用程序可以非常简单,只有一个类:
@ mcdizle的解决方案不起作用它只适用于一个条目 .
这个适用于具有相同前缀的所有密钥
Note: 您应该用您的密钥前缀替换'prefix' ...
如果密钥名称中有空格,则可以在bash中使用:
Spring RedisTemplate本身提供了这些功能 . 最新版本中的RedissonClient已弃用“deleteByPattern”功能 .