【问题标题】:Deleting multiple keys in a redis cluster删除redis集群中的多个key
【发布时间】:2020-04-19 04:55:05
【问题描述】:

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

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

方法1.循环按键,使用围棋套路+权重组

方法 2. 使用 EVAL :我不确定这是否是正确的方向,或者我是否正确使用它。以下是下面的示例golang sn-p

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 包本身的解决方案,那就太好了。

【问题讨论】:

  • 这能回答你的问题吗? Redis Cross Slot error
  • 部分是。帮助我理解 Lua 在这里不会有帮助。但我仍然想在这里了解可能的选择。最好是哈希标签或限制哈希槽的键
  • @rajat 您可能要考虑使用 RedisGears,它允许您运行跨槽/分片操作

标签: go redis redis-cluster


【解决方案1】:

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

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

  1. 使用 Redis hash tags。这意味着如果您在所有键中都有一个公共子字符串(例如["mykey_a", "mykey_b", ...]),那么您可以通过在公共子字符串(["{mykey}_a", "{mykey}_b", ...])周围添加花括号来强制 Redis 将所有键分组到同一个插槽。显然,不建议为您的所有键使用相同的插槽,但如果您可以将其中的一些分组用于特定目的,那么这个解决方案是有效的。

  2. 使用Redis pipelines。这样,您单独执行每个DEL 命令,但保存网络 RTT。 Go 中的管道可能如下所示:

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

【讨论】:

  • 我认为单个管道不会自动将命令分片到单独的集群节点。
  • 感谢您的指导。我将尝试一次管道,因为我现在想避免将密钥限制在哈希槽中。但是 goroutines 是一个坏主意还是一个选项?
猜你喜欢
  • 2017-04-02
  • 2018-05-05
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
相关资源
最近更新 更多