- 用法
-
CLUSTER FORGET node-id
- 复杂度
- O(1)
- 自
- 3.0.0
- ACL 类别
- @admin, @dangerous, @slow
- 将所有哈希槽从 D 重新分片到节点 A、B、C。
- D 现在是空的,但仍然列在 A、B 和 C 的节点表中。
- 我们联系 A,并发送
CLUSTER FORGET D
。 - B 向节点 A 发送一个心跳包,其中列出了节点 D。
- A 不再知道节点 D(参见步骤 3),因此它与 D 开始握手。
- D 最终被重新添加到 A 的节点表中。
- 指定节点将从节点表中移除。
- 被移除节点的节点 ID 将被添加到禁止列表,有效期为 1 分钟。
- 当处理从其他节点接收到的心跳包中的 gossip 部分时,该节点将跳过禁止列表中列出的所有节点 ID。
- 在节点表中找不到指定的节点 ID。
- 接收命令的节点是副本,并且指定的节点 ID 标识了其当前的主节点。
- 节点 ID 标识的是我们发送命令的同一节点。
此命令用于将通过其节点 ID 指定的节点从接收命令的 Valkey 集群节点的*已知节点*集合中移除。换句话说,指定的节点将从接收命令的节点的*节点表*中移除。
因为当给定节点是集群的一部分时,集群中所有其他参与节点都会知道它。为了将一个节点从集群中完全移除,必须将 CLUSTER FORGET
命令发送给所有剩余节点,无论它们是主节点还是副本节点。
然而,该命令不能简单地从接收命令的节点的内部节点表中删除该节点,它还实现了一个禁止列表,防止同一节点因处理从其他节点接收到的心跳包的*gossip 部分*而被再次添加。
禁止列表的必要性详情
在以下示例中,我们将展示为什么该命令不仅需要从节点表中移除给定节点,还需要在一段时间内阻止其被重新插入。
假设我们有四个节点:A、B、C 和 D。为了最终得到一个由 A、B、C 三个节点组成的集群,我们可以遵循以下步骤:
正如你所看到的,以这种方式移除节点是脆弱的,我们需要尽快向所有节点发送 CLUSTER FORGET
命令,希望在此期间没有 gossip 部分正在处理。由于这个问题,该命令实现了一个禁止列表,其中每个条目都有一个过期时间。
所以该命令真正做的是:
这样我们就有 60 秒的时间窗口来通知集群中的所有节点我们要移除一个节点。
不允许执行命令的特殊条件
在以下情况下,该命令不会成功并返回错误:
RESP2/RESP3 回复
简单字符串回复:如果命令成功执行,则为 OK
。否则返回错误。