CLUSTER FORGET

语法
CLUSTER FORGET node-id
可用版本
Redis 开源版 3.0.0
时间复杂度
O(1)
ACL 类别
@admin, @slow, @dangerous,

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

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

然而,该命令不能简单地从接收命令的节点的内部节点表中删除该节点,它还实现了一个禁止列表,以防止由于处理从其他节点接收到的心跳包的*流言部分*而导致同一节点被再次添加。

从 Redis 7.2.0 开始,禁止列表包含在集群流言 ping/pong 消息中。这意味着 CLUSTER FORGET 命令不需要发送给集群中的所有节点。您可以在一个或多个节点上运行此命令,之后在大多数情况下它会传播到其他节点。

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

在以下示例中,我们将说明为什么该命令不仅要从节点表中移除给定节点,还要防止它在一段时间内被再次插入。

假设我们有四个节点 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 命令发送给所有节点,希望在此期间没有流言部分正在处理。由于这个问题,该命令实现了一个禁止列表,其中每个条目都有一个过期时间。

因此,该命令实际执行的操作是

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

通过这种方式,我们有 60 秒的时间窗口通知集群中的所有节点我们要移除一个节点。

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

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

  1. 在节点表中找不到指定的节点 ID。
  2. 接收命令的节点是一个副本节点,并且指定的节点 ID 是其当前主节点的 ID。
  3. 节点 ID 是我们发送命令的目标节点本身的 ID。

行为变更历史

  • >= 7.2.0:自动将节点删除传播到集群中的其他节点,在大多数情况下允许通过一次调用删除节点。

RESP2/RESP3 回复

简单字符串回复:如果命令执行成功,则返回 OK。否则返回错误。

历史

  • 从 Redis 7.2.0 版本开始:被遗忘的节点通过流言自动在集群中传播。
评价此页
返回顶部 ↑