【问题标题】:delete redis hash values in bulk based on the hash key name根据散列键名批量删除redis散列值
【发布时间】:2013-06-17 23:16:15
【问题描述】:

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

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

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

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

任何建议将不胜感激。

【问题讨论】:

    标签: lua redis command-line-interface


    【解决方案1】:

    以下EVAL script 应该做你想做的事:

    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 测试)

    【讨论】:

    • 我应该澄清一下,我不需要原子操作。有没有简单的方法让它在运行时允许其他呼叫通过?
    • 只是为了我的理解,脚本正在执行以下操作?
    • 对不起,我在手机上写东西...我会试一试,并尝试了解您如何/为什么以这种方式编写脚本。我可能会向您发送另一个问题。 :)
    • 我终于试了一下,似乎它删除了所有包含“cc_”的东西,而不是所有以“cc_”开头的东西。例如,我试图删除所有这些“cc_XX”键,同时保留所有新的键,例如“metadata_cc_XX”和“metadata_cc_XX_ts”,但在运行“cc_..”时它们都被删除了。任何建议将不胜感激。
    • 啊哈,更多的正则表达式风格,我以为它只是带了一个通配符。谢谢!
    【解决方案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
    

    【讨论】:

      猜你喜欢
      • 2011-02-03
      • 2015-02-03
      • 2017-06-16
      • 1970-01-01
      • 2015-01-26
      • 1970-01-01
      • 2023-03-24
      • 2015-09-18
      • 2021-02-04
      相关资源
      最近更新 更多