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