3

与此类似,但需要哈希而不是普通键的解决方案: How to atomically delete keys matching a pattern using Redis

我有一堆带有前缀的哈希,例如:“前缀:”

在每个哈希下是一堆键,例如:“cc_XX”,其中“XX”是一个 2 个字母的代码。

我需要一些如何遍历我所有的 redis 哈希,并以某种方式删除每个 cc_XX 子键,并且正在寻找一种 cli/lua 方法来做到这一点(两者都不是很好)。

任何建议将不胜感激。

4

2 回答 2

6

下面的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 测试)

于 2013-06-21T14:38:04.237 回答
2

我们在 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
于 2015-10-07T16:56:17.263 回答