CLUSTER SETSLOT

用法
CLUSTER SETSLOT slot 〈 IMPORTING importing | MIGRATING migrating | NODE node | STABLE 〉 [ TIMEOUT timeout ]
复杂度
O(1)
起始版本
3.0.0
ACL 类别
@admin, @dangerous, @slow

CLUSTER SETSLOT 负责以不同方式更改接收节点中哈希槽的状态。根据所使用的子命令,它可以

  1. MIGRATING 子命令:将哈希槽设置为迁移中状态。
  2. IMPORTING 子命令:将哈希槽设置为导入中状态。
  3. STABLE 子命令:清除哈希槽的任何导入中/迁移中状态。
  4. NODE 子命令:将哈希槽绑定到不同的节点。

该命令及其子命令集可用于启动和结束集群实时再分片操作,这些操作通过将源节点中的哈希槽设置为迁移中状态,以及目标节点中的哈希槽设置为导入中状态来完成。

每个子命令都在下面文档中列出。最后,您将找到关于如何使用此命令和其他相关命令执行实时再分片的描述。

CLUSTER SETSLOT <slot> MIGRATING <destination-node-id>

此子命令将槽设置为迁移中状态。为了将槽设置为此状态,接收命令的节点必须是哈希槽的所有者,否则将返回错误。

当槽设置为迁移中状态时,节点的行为会发生如下变化:

  1. 如果收到关于现有键的命令,该命令照常处理。
  2. 如果收到关于不存在的键的命令,节点将发出一个 ASK 重定向,要求客户端仅将该特定查询重试到 destination-node。在这种情况下,客户端不应更新其哈希槽到节点的映射。
  3. 如果命令包含多个键,在所有键都不存在的情况下,行为与第2点相同;如果所有键都存在,行为与第1点相同;但是,如果只有部分键存在,命令会发出一个 TRYAGAIN 错误,以便相关键完成迁移到目标节点,从而可以执行多键命令。

CLUSTER SETSLOT <slot> IMPORTING <source-node-id>

此子命令与 MIGRATING 相反,它准备目标节点从指定的源节点导入键。该命令仅在节点尚未拥有指定哈希槽时才有效。

当槽设置为导入中状态时,节点的行为会发生如下变化:

  1. 关于此哈希槽的命令通常会被拒绝并生成 MOVED 重定向,但在命令紧随 ASKING 命令的情况下,此命令会被执行。

这样,当处于迁移状态的节点生成 ASK 重定向时,客户端会联系目标节点,发送 ASKING,然后立即发送命令。通过这种方式,关于旧节点中不存在的键或已迁移到目标节点的键的命令都在目标节点中执行,因此:

  1. 新键始终在目标节点中创建。在哈希槽迁移过程中,我们只需移动旧键,而不是新键。
  2. 关于已迁移键的命令在作为迁移目标的节点(新的哈希槽所有者)的上下文中得到正确处理,以确保一致性。
  3. 如果没有 ASKING,行为与平时相同。这保证了具有错误哈希槽映射的客户端不会错误地写入目标节点,从而创建尚未迁移的键的新版本。

CLUSTER SETSLOT <slot> STABLE

此子命令仅清除槽的迁移中/导入中状态。它主要用于通过 valkey-cli --cluster fix 修复集群卡在错误状态的问题。通常,这两个状态在迁移结束时使用 SETSLOT ... NODE ... 子命令(如下一节所述)自动清除。

CLUSTER SETSLOT <slot> NODE <node-id>

NODE 子命令具有最复杂的语义。它将哈希槽与指定的节点关联,但该命令仅在特定情况下有效,并且根据槽的状态具有不同的副作用。以下是该命令的前提条件和副作用:

  1. 如果当前哈希槽所有者是接收命令的节点,但由于命令的效果槽将被分配给不同的节点,则如果接收命令的节点中仍存在该哈希槽的键,命令将返回错误。
  2. 如果槽处于迁移中状态,当槽被分配给另一个节点时,该状态将被清除。
  3. 如果槽在接收命令的节点中处于导入中状态,并且命令将槽分配给此节点(这在哈希槽从一个节点再分片到另一个节点结束时发生在目标节点中),则该命令具有以下副作用:A) 导入中状态被清除。B) 如果节点配置 epoch 尚未是集群中最大的,它将生成一个新的并将其分配给自己。这样,其新的哈希槽所有权将优于任何过去由之前的故障转移或槽迁移创建的配置。

重要的是要注意,步骤3是 Valkey 集群节点在未经其他节点同意的情况下创建新配置 epoch 的唯一时间。这仅在手动配置操作时发生。然而,这不可能创建一个非瞬态设置,即两个节点具有相同的配置 epoch,因为 Valkey 集群使用配置 epoch 冲突解决算法。

Valkey 集群实时再分片详解

CLUSTER SETSLOT 命令是 Valkey 集群用于将一个哈希槽中包含的所有键从一个节点迁移到另一个节点的重要组成部分。以下是借助其他命令协调迁移的方式。我们将当前拥有哈希槽所有权的节点称为 source 节点,将我们希望迁移到的节点称为 destination 节点。

  1. 使用 CLUSTER SETSLOT <slot> IMPORTING <source-node-id> 将目标节点槽设置为导入中状态。
  2. 使用 CLUSTER SETSLOT <slot> MIGRATING <destination-node-id> 将源节点槽设置为迁移中状态。
  3. 使用 CLUSTER GETKEYSINSLOT 命令从源节点获取键,并使用 MIGRATE 命令将它们移动到目标节点。
  4. CLUSTER SETSLOT <slot> NODE <destination-node-id> 发送到目标节点。
  5. CLUSTER SETSLOT <slot> NODE <destination-node-id> 发送到源节点。
  6. CLUSTER SETSLOT <slot> NODE <destination-node-id> 发送到其他主节点(可选)。

注意事项

  • 步骤1和2的顺序很重要。我们希望当源节点配置为重定向时,目标节点已准备好接受 ASK 重定向。

  • 步骤4和5的顺序很重要。目标节点负责将更改传播到集群的其余部分。如果在目标节点之前通知源节点,并且目标节点在被设置为新槽所有者之前崩溃,则即使在成功故障转移后,该槽也将处于无所有者状态。

  • 步骤6,向未参与再分片的节点发送 SETSLOT,从技术上讲并非必需,因为配置最终会自行传播。但是,这样做是个好主意,以便尽快阻止节点指向移动哈希槽的错误节点,从而减少查找正确节点所需的重定向次数。

  • 从 Valkey 8.0 开始,CLUSTER SETSLOT 会同步复制到所有运行 Valkey 8.0+ 版本的健康副本。默认情况下,此同步复制必须在2秒内完成。如果复制失败,主节点不会执行该命令,客户端会收到 NOREPLICAS Not enough good replicas to write 错误。操作员可以重试该命令,或者使用 TIMEOUT 参数自定义超时时间,以进一步提高实时重新配置的可靠性。

    CLUSTER SETSLOT slot [MIGRATING|IMPORTING|NODE] node-id [TIMEOUT timeout]
    

    此处,timeout 以秒为单位,0 表示无限期等待。

RESP2/RESP3 回复

简单字符串回复:如果命令成功,所有子命令都返回 OK。否则返回错误。

历史

版本 变更
8.0.0

添加了 TIMEOUT 选项。