Redis CLUSTER FORGET 命令从收到命令的 Redis 集群节点的节点信息列表中移除指定 ID 的节点。该命令不仅将待删除节点的信息简单从内部配置中删除,同时不允许已删除的节点再次被添加进来,否则,已删除节点会因为处理其他节点心跳包中的 gossip section 时,被再次添加。
命令格式
CLUSTER FORGET node-id
可用版本:>=3.0.0
时间复杂度:O(1)
命令执行的明细
在下面的示例中,我们将说明为什么该命令不仅必须从节点表中删除指定的节点,而且还必须防止在一段时间内再次将其重新插入。
假设我们有四个节点,A、B、C、D。为了得到一个 3 个节点的集群(包括 A、B、C),我们可以做如下操作:
- 将节点 D 上的哈希槽重分配到节点 A,B,C。
- 此时,节点 D 现在已经空了,但是节点 A,B,C 的节点信息表中仍然存有节点 D 的信息。
- 我们连接节点 A,发送命令
CLUSTER FORGET D
。 - 节点 B 发送心跳包给节点 A,其中包含节点 D 的信息。
- 由于此时,节点 A 无节点 D 信息,因此,节点 A 开始与节点 D 握手。
- 这样,节点 D 最终再次添加进节点 A 的节点信息表中。
上述的移除方法很不稳定,因此我们需要尽快发送命令 CLUSTER FORGET 给所有节点,以期没有 gossip sections 在同时处理。因为这个原因,命令 CLUSTER FORGET 为每个节点实现了包含超时时间的禁止列表。
因此我们命令实际的执行情况如下:
- 从收到命令节点的节点信息列表中删除待删除节点的节点信息。
- 已删除的节点的节点 ID 被加入禁止列表,并保留 1 分钟。
- 收到命令的节点,在处理从其他节点发送过来的 gossip sections 会跳过所有在禁止列表中的节点。
这样,我们就有 60 秒的时间窗口来通知集群中的所有节点来进行我们想要删除某个节点操作。
命令不可执行的特殊条件
在如下情况下,该命令无法成功执行,并返回错误:
- 节点信息表中无法找到指定删除节点的节点信息。
- 收到命令的节点是 slave 节点,指定要删除的节点被识别出是它当前的 master 节点。
- 收到命令的节点和待删除的节点是同一节点。
命令返回值
命令成功执行,返回 OK,否则返回错误。