go之删除redis集群中的多个key

xing901022 阅读:36 2025-06-02 22:19:02 评论:0

据我了解,在 redis 集群中,插槽是分布式的,DEL可以使用多个键的命令失败并返回 CROSSSLOT Keys in request don't hash to the same slot错误。

由于我现有的代码库是围绕批处理设计的,所以在很多地方都会调用 redis 缓存删除操作并使用要删除的键列表。因为改变这不是一个聪明的主意我试图在我的缓存接口(interface)层找到一个解决方案,在那里我仍然可以接收要删除的多个键并在此处添加所需的逻辑以实现相同的最终结果。 在我看来,我有两个选择需要帮助

方法一。循环按键并使用 Go 例程 + 重量组

方法二。使用EVAL : 我不确定这是否是正确的方向,或者我是否正确使用它。以下是下面的示例 golang 片段

func (c CacheClient) Del(ctx context.Context, keysToBeDeleted []string) error { 
    // _, err := c.client.Del(strings.Join(keysToBeDeleted, " ")).Result() // previously used when on single redis instance 
    _, err := c.client.Eval("return redis.call('DEL', KEYS[1])", keysToBeDeleted).Result() 
 
    if err != nil { 
        // handle error 
    } 
    return nil 
} 

我创建了一个虚拟集群并使用 redis-cli 来测试 eval 命令,如下所示
redis> EVAL "redis.call('del', KEYS[1]) " 2 mykey1, mykey2
这也失败了 CROSSSLOT Keys in request don't hash to the same slot错误。

我是否在 Lua 脚本中以错误的方式使用了 KEYS 表。或者从集群中删除多个键的正确方法是什么。我应该坚持方法1吗?

使用 Golang v1.13 和 redis.v5作为我的 redis-client 包。
如果有人可以帮助我找到使用 redis.v5 包本身的解决方案,那就太好了。

请您参考如下方法:

我不确定使用 Lua 脚本是否会帮助您。 Lua 脚本有利于强制原子性,但不会帮助您克服多个插槽的问题。

您的问题的两种可能的解决方案是:

  • 使用 Redis hash tags .这意味着如果您在所有键中都有一个公共(public)子字符串(例如 ["mykey_a", "mykey_b", ...] ),那么您可以通过在公共(public)子字符串( ["{mykey}_a", "{mykey}_b", ...] )周围添加花括号来强制 Redis 将所有键分组到同一个槽中。显然,不建议为所有 key 使用相同的插槽,但如果您可以将其中一些分组用于特定目的,那么此解决方案是有效的。
  • 使用Redis pipelines .这样,您执行每个 DEL单独命令,但保存网络 RTT。 Go 中的流水线如下所示:

  • pipe := c.client.Pipeline() 
    for _, key := range keys { 
        pipe.Del(key) 
    } 
    pipe.Exec() 
    


    标签:Redis
    声明

    1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

    关注我们

    一个IT知识分享的公众号