CLUSTER SETSLOT
CLUSTER SETSLOT slot <IMPORTING node-id | MIGRATING node-id | NODE node-id | STABLE>
- 可用版本
- Redis Open Source 3.0.0
- 时间复杂度
- O(1)
- ACL 类别
-
@admin
,@slow
,@dangerous
,
CLUSTER SETSLOT
命令负责以不同方式改变接收节点中哈希槽的状态。根据使用的子命令,它可以
MIGRATING
子命令:将哈希槽设置为 *迁移中* (migrating) 状态。IMPORTING
子命令:将哈希槽设置为 *导入中* (importing) 状态。STABLE
子命令:清除哈希槽的任何导入中 / 迁移中状态。NODE
子命令:将哈希槽绑定到另一个节点。
这个命令及其子命令集合对于启动和结束集群实时重新分片操作非常有用,这些操作通过将源节点中的哈希槽设置为迁移中状态,并将目标节点中的哈希槽设置为导入中状态来实现。
每个子命令都在下方文档中说明。最后你会找到关于如何使用此命令及其他相关命令执行实时重新分片操作的描述。
CLUSTER SETSLOT <slot>
MIGRATING <destination-node-id>
此子命令将槽设置为 *迁移中* (migrating) 状态。为了将槽设置为此状态,接收命令的节点必须是该哈希槽的所有者,否则会返回错误。
当槽设置为迁移中状态时,节点的行为会发生以下变化:
- 如果收到关于现有键的命令,命令会照常处理。
- 如果收到关于不存在键的命令,节点会发出 `ASK` 重定向,要求客户端仅在该特定查询中重试到 `destination-node`。在这种情况下,客户端不应更新其哈希槽到节点的映射。
- 如果命令包含多个键,如果所有键都不存在,行为与第 2 点相同;如果所有键都存在,行为与第 1 点相同;但如果只有部分键存在,命令会发出 `TRYAGAIN` 错误,以便相关键可以完成迁移到目标节点,从而可以执行多键命令。
CLUSTER SETSLOT <slot>
IMPORTING <source-node-id>
此子命令与 `MIGRATING` 相反,用于准备目标节点从指定的源节点导入键。该命令仅在该节点不是指定哈希槽的所有者时有效。
当槽设置为导入中状态时,节点的行为会发生以下变化:
- 关于此哈希槽的命令通常会被拒绝并生成 `MOVED` 重定向,但如果命令紧随一个
ASKING
命令之后,则命令会被执行。
通过这种方式,当处于迁移中状态的节点生成 `ASK` 重定向时,客户端会联系目标节点,发送 `ASKING`,然后立即发送命令。这样一来,关于旧节点中不存在的键或已迁移到目标节点的键的命令都会在目标节点上执行,从而:
- 新键始终在目标节点中创建。在哈希槽迁移期间,我们只需移动旧键,而不是新键。
- 关于已迁移键的命令会在迁移目标节点(新的哈希槽所有者)的上下文中正确处理,以保证一致性。
- 如果没有
ASKING
,行为与通常相同。这保证了哈希槽映射损坏的客户端不会错误地写入目标节点,从而为尚未迁移的键创建新版本。
CLUSTER SETSLOT <slot>
STABLE
此子命令仅清除槽的迁移中 / 导入中状态。它主要用于通过 `redis-cli --cluster fix` 修复集群卡在错误状态的问题。通常,如下一节所述,在迁移结束时使用 `SETSLOT ... NODE ...` 子命令会自动清除这两种状态。
CLUSTER SETSLOT <slot>
NODE <node-id>
NODE
子命令语义最复杂。它将哈希槽与指定节点关联起来,但该命令仅在特定情况下有效,并且根据槽的状态具有不同的副作用。以下是该命令的一系列前置条件和副作用:
- 如果当前哈希槽的所有者是接收命令的节点,但该命令将槽分配给另一个节点,并且接收命令的节点中仍有该哈希槽的键,则命令将返回错误。
- 如果槽处于 *迁移中* (migrating) 状态,当槽被分配给另一个节点时,该状态会被清除。
- 如果接收命令的节点中槽处于 *导入中* (importing) 状态,并且命令将槽分配给此节点(这发生在将哈希槽从一个节点重新分片到另一个节点结束时的目标节点),则该命令具有以下副作用:A) 清除 *导入中* 状态。B) 如果节点的配置纪元 (config epoch) 尚未是集群中最大的,它将生成一个新的配置纪元并将其分配给自己。这样,其新的哈希槽所有权将胜过之前由故障转移或槽迁移创建的任何旧配置。
需要注意的是,第 3 步是 Redis Cluster 节点在未与其他节点达成一致的情况下创建新配置纪元 (config epoch) 的唯一情况。这仅在手动配置操作时发生。然而,这不可能创建两个节点具有相同配置纪元的非临时性设置,因为 Redis Cluster 使用配置纪元冲突解决算法。
Redis Cluster 实时重新分片解释
CLUSTER SETSLOT
命令是 Redis Cluster 用于将一个哈希槽中包含的所有键从一个节点迁移到另一个节点的重要组成部分。以下是借助其他命令协调迁移的方式。我们将当前拥有哈希槽所有权的节点称为 `source` (源) 节点,将我们要迁移到的节点称为 `destination` (目标) 节点。
- 使用 `CLUSTER SETSLOT
IMPORTING ` 命令将目标节点槽设置为 *导入中* (importing) 状态。 - 使用 `CLUSTER SETSLOT
MIGRATING ` 命令将源节点槽设置为 *迁移中* (migrating) 状态。 - 使用
CLUSTER GETKEYSINSLOT
命令从源节点获取键,并使用 `MIGRATE` 命令将它们移动到目标节点。 - 向目标节点发送 `CLUSTER SETSLOT
NODE ` 命令。 - 向源节点发送 `CLUSTER SETSLOT
NODE ` 命令。 - 向其他主节点发送 `CLUSTER SETSLOT
NODE ` 命令(可选)。
注意
- 步骤 1 和 2 的顺序很重要。我们希望在源节点配置为重定向时,目标节点已准备好接受 `ASK` 重定向。
- 步骤 4 和 5 的顺序很重要。目标节点负责将更改传播到集群的其余部分。如果在目标节点之前通知了源节点,并且目标节点在被设置为新槽所有者之前崩溃,则该槽将没有所有者,即使在成功的故障转移后也是如此。
- 步骤 6,向未参与重新分片的节点发送 `SETSLOT` 命令,技术上不是必需的,因为配置最终会自行传播。但是,这样做是一个好主意,以便尽快停止节点指向已移动哈希槽的错误节点,从而减少查找正确节点的重定向次数。
RESP2/RESP3 回复
简单字符串回复:如果命令成功,所有子命令都返回OK
。否则返回错误。