集群忘记

Syntax
CLUSTER FORGET node-id
Available since:
3.0.0
Time complexity:
O(1)
ACL categories:
@admin, @slow, @dangerous,

该命令用于从接收命令的Redis集群节点的已知节点集合中移除一个节点,该节点通过其节点ID指定。换句话说,指定的节点将从接收命令的节点的节点表中移除。

因为当一个给定的节点是集群的一部分时,所有参与集群的其他节点都知道它,所以为了将一个节点完全从集群中移除,必须向所有剩余的节点发送CLUSTER FORGET命令,无论它们是主节点还是副本节点。

然而,命令不能简单地从接收命令的节点的内部节点表中删除节点,它还实现了一个禁止列表,不允许在处理从其他节点接收到的心跳包的gossip部分时再次添加相同的节点。

关于为什么需要禁止列表的详细信息

在下面的例子中,我们将展示为什么命令不仅要从节点表中删除给定的节点,还要防止它在一段时间内被重新插入。

假设我们有四个节点,A、B、C 和 D。为了最终只得到一个包含三个节点的集群 A、B、C,我们可以按照以下步骤进行:

  1. 将所有哈希槽从D重新分片到节点A、B、C。
  2. D 现在为空,但仍然列在 A、B 和 C 的节点表中。
  3. 我们联系A,并发送CLUSTER FORGET D
  4. B 向节点 A 发送一个心跳包,其中列出了节点 D。
  5. A 不再知道节点 D(参见步骤 3),因此它开始与 D 进行握手。
  6. D 结束重新添加到 A 的节点表中。

正如你所见,这种方式移除节点是脆弱的,我们需要尽快向所有节点发送CLUSTER FORGET命令,希望在此期间没有正在处理的gossip部分。由于这个问题,该命令实现了一个带有每个条目过期时间的禁止列表。

所以这个命令真正做的是:

  1. 指定的节点从节点表中移除。
  2. 被移除节点的节点ID会被添加到禁止列表中,持续1分钟。
  3. 节点在处理从其他节点接收到的心跳包中的gossip部分时,将跳过ban-list中列出的所有节点ID。

这样我们有一个60秒的时间窗口来通知集群中的所有节点我们想要移除一个节点。

不允许执行命令的特殊条件

命令在以下情况下不会成功并返回错误:

  1. 在节点表中未找到指定的节点ID。
  2. 接收命令的节点是一个副本,指定的节点ID标识其当前的主节点。
  3. 节点ID标识了我们正在发送命令的同一节点。

RESP2/RESP3 回复

Simple string reply: OK if the command was executed successfully. Otherwise an error is returned.
RATE THIS PAGE
Back to top ↑