集群 FORGET
语法
CLUSTER FORGET node-id
- 从以下位置开始可用:
- 3.0.0
- 时间复杂度:
- O(1)
- ACL 类别:
-
@admin
,@slow
,@dangerous
,
该命令用于删除通过其节点 ID 指定的节点 从接收命令的 Redis Cluster 节点的已知节点集中。 换句话说,指定的节点将从 节点。
因为当给定节点是集群的一部分时,所有其他节点
参与集群知道它,以便节点
完全从集群中删除,则CLUSTER FORGET
command 必须为
发送到所有剩余节点,无论它们是否是 master 节点
或副本。
但是,该命令不能简单地从内部节点中删除节点 table 中,它还实现了一个 ban-list,而不是 允许再次添加同一节点,作为处理从其他节点接收的检测信号数据包的 gossip 部分的副作用。
从 Redis 7.2.0 开始,禁止列表包含在集群 gossip ping/pong 消息中。
这意味着CLUSTER FORGET
不需要发送到集群中的所有节点。
您可以在一个或多个节点上运行该命令,之后在大多数情况下,该命令将传播到其余节点。
有关为什么需要 ban list 的详细信息
在下面的示例中,我们将说明为什么该命令不能只删除 来自 nodes 表中的给定节点,但也要防止它被重新插入 又持续了一段时间。
假设我们有四个节点,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 的 nodes 表中。
正如你所看到的,以这种方式删除一个节点是脆弱的,我们需要发送CLUSTER FORGET
命令尽快发送到所有节点,希望没有
gossip 部分正在处理。由于这个问题,
command 实现一个 ban-list,每个条目都有一个过期时间。
所以这个命令的真正作用是:
- 指定的节点将从 nodes 表中删除。
- 已删除节点的节点 ID 将添加到禁止列表中,持续 1 分钟。
- 该节点在处理从其他节点接收到的心跳数据包中的 gossip 部分时,将跳过 ban-list 中列出的所有节点 ID。
这样,我们就有 60 秒的窗口来通知集群中的所有节点 我们想要删除一个节点。
不允许命令执行的特殊条件
在以下情况下,该命令不会成功并返回错误:
- 在 nodes 表中找不到指定的节点 ID。
- 接收命令的节点是副本,指定的节点 ID 标识其当前 master。
- 节点 ID 标识我们要将命令发送到的同一节点。
行为更改历史记录
>= 7.2.0
:自动将节点删除传播到集群中的其他节点,允许通过一次调用删除节点 在大多数情况下。
RESP2/RESP3 回复
简单的字符串回复:OK
如果命令执行成功。否则,将返回错误。历史
- 从 Redis 版本 7.2.0 开始:被遗忘的节点会通过 gossip 自动传播到整个集群中。