与此类似,但需要哈希而不是普通键的解决方案: How to atomically delete keys matching a pattern using Redis
我有一堆带有前缀的哈希,例如:“前缀:”
在每个哈希下是一堆键,例如:“cc_XX”,其中“XX”是一个 2 个字母的代码。
我需要一些如何遍历我所有的 redis 哈希,并以某种方式删除每个 cc_XX 子键,并且正在寻找一种 cli/lua 方法来做到这一点(两者都不是很好)。
任何建议将不胜感激。
与此类似,但需要哈希而不是普通键的解决方案: How to atomically delete keys matching a pattern using Redis
我有一堆带有前缀的哈希,例如:“前缀:”
在每个哈希下是一堆键,例如:“cc_XX”,其中“XX”是一个 2 个字母的代码。
我需要一些如何遍历我所有的 redis 哈希,并以某种方式删除每个 cc_XX 子键,并且正在寻找一种 cli/lua 方法来做到这一点(两者都不是很好)。
任何建议将不胜感激。
下面的EVAL 脚本应该做你想做的事:
local keys = redis.call('KEYS',KEYS[1])
for i,k in ipairs(keys) do
local res = redis.call('HKEYS',k)
for j,v in ipairs(res) do
if string.find(v,ARGV[1]) then
redis.call('HDEL',k,v)
end
end
end
您需要通过提供以下参数来调用它:
EVAL <script> 1 prefix:* cc_..
请注意,它会阻塞 Redis 事件循环,直到脚本完成,因此如果您有大量键,它可以冻结 Redis 一段时间。原子性是有代价的。
更新:
如果您不需要原子性,那么以下脚本将避免阻塞 Redis 太长时间(但请注意,如果您有大量的全局键或您的哈希对象之一很大,它仍然会阻塞:有没有办法避免这种情况)。
./redis-cli keys 'prefix:*' | awk '
BEGIN {
script = "local res = redis.call('\''HKEYS'\'',KEYS[1]); \
for j,v in ipairs(res) do \
if string.find(v,ARGV[1]) then \
redis.call('\''HDEL'\'',KEYS[1],v); \
end \
end"
}
{
printf "EVAL \"%s\" 1 %s cc_..\n", script, $1
}' | ./redis-cli
(用 bash 测试)
我们在 Redis 中存储哈希的方式是,我们通过哈希中的对象类型为哈希元素 id 键添加后缀。有时在数据模型中,我们更新一个对象,我们需要在部署时删除给定对象类型的所有哈希元素。我们希望在不必删除整个哈希的情况下完成此操作。
例如:
127.0.0.1:6379> keys client*
1) "client"
127.0.0.1:6379> type client
hash
127.0.0.1:6379> hkeys client
1) "123-obj1"
2) "123-obj2"
3) "123-obj3"
4) "123-obj4"
5) "123-obj5"
6) "456-obj1"
7) "456-obj2"
8) "456-obj3"
9) "456-obj4"
10) "456-obj5"
如果我们在应用程序中向 obj5 添加一个新字段并设置为默认值,我们将需要运行“HDEL client *-obj5”的等效项。但是,这在 redis-cli 中不起作用。
我通过 BASH 找到了以下作品:
redis-cli HKEYS 'client' | grep obj5 | awk '{ printf "HDEL client %s\n", $1 }' | redis-cli
如果你在你的环境中使用不同的 Redis 数据库,请添加“-n X”开关,相当于 redis-cli 中的“select X”。在这种情况下,选择数据库 4:
redis-cli -n 4 HKEYS 'client' | grep obj5 | awk '{ printf "HDEL client %s\n", $1 }' | redis-cli -n 4