Redis集群规范(二)

来源:互联网 发布:淘宝漏洞最新 编辑:程序博客网 时间:2024/05/21 19:56

容错

节点失效检测

以下是节点失效检查的实现方法:

  • 当一个节点向另一个节点发送 PING 命令, 但是目标节点未能在给定的时限内返回 PING 命令的回复时, 那么发送命令的节点会将目标节点标记为 PFAIL (possible failure,可能已失效)。

    等待 PING 命令回复的时限称为“节点超时时限(node timeout)”, 是一个节点选项(node-wise setting)。

  • 每次当节点对其他节点发送 PING 命令的时候, 它都会随机地广播三个它所知道的节点的信息, 这些信息里面的其中一项就是说明节点是否已经被标记为 PFAIL 或者 FAIL 。

  • 节点接收到其他节点发来的信息时, 它会记下那些被其他节点标记为失效的节点。 这称为失效报告(failure report)。

  • 如果节点已经将某个节点标记为 PFAIL , 并且根据节点所收到的失效报告显式, 集群中的大部分其他主节点也认为那个节点进入了失效状态, 那么节点会将那个失效节点的状态标记为 FAIL

  • 一旦某个节点被标记为 FAIL , 关于这个节点已失效的信息就会被广播到整个集群, 所有接收到这条信息的节点都会将失效节点标记为 FAIL 。

简单来说, 一个节点要将另一个节点标记为失效, 必须先询问其他节点的意见, 并且得到大部分主节点的同意才行。

因为过期的失效报告会被移除, 所以主节点要将某个节点标记为 FAIL 的话, 必须以最近接收到的失效报告作为根据。

在以下两种情况中, 节点的 FAIL 状态会被移除:

  • 如果被标记为 FAIL 的是从节点, 那么当这个节点重新上线时, FAIL 标记就会被移除。

    保持从节点的 FAIL 状态是没有意义的, 因为它不处理任何槽, 一个从节点是否处于 FAIL 状态, 决定了这个从节点在有需要时能否被提升为主节点。

  • 如果一个主节点被打上 FAIL 标记之后, 经过了节点超时时限的四倍时间, 再加上十秒钟之后, 针对这个主节点的槽的故障转移操作仍未完成, 并且这个主节点已经重新上线的话, 那么移除对这个节点的 FAIL 标记。

    (针对fall主节点的迁移操作未完成,且该主节点已经重新上线,则移除fall标记,集群继续使用原来的主节点)

集群状态检测(已部分实现)

每当集群发生配置变化时(可能是哈希槽更新,也可能是某个节点进入失效状态), 集群中的每个节点都会对它所知道的节点进行扫描(scan)。

一旦配置处理完毕, 集群会进入以下两种状态的其中一种:

  • FAIL : 集群不能正常工作。 当集群中有某个节点进入失效状态时, 集群不能处理任何命令请求, 对于每个命令请求, 集群节点都返回错误回复。

  • OK : 集群可以正常工作, 负责处理全部 16384 个槽的节点中, 没有一个节点被标记为 FAIL 状态。
    这说明即使集群中只有一部分哈希槽不能正常使用, 整个集群也会停止处理任何命令。
    不过节点从出现问题到被标记为 FAIL 状态的这段时间里, 集群仍然会正常运作, 所以集群在某些时候, 仍然有可能只能处理针对16384 个槽的其中一个子集的命令请求。

以下是集群进入 FAIL 状态的两种情况:

  1. 至少有一个哈希槽不可用,因为负责处理这个槽的节点进入了 FAIL 状态。
  2. 集群中的大部分主节点都进入下线状态。当大部分主节点都进入 PFAIL 状态时,集群也会进入 FAIL 状态。

第二个检查是必须的, 因为要将一个节点从 PFAIL 状态改变为 FAIL 状态, 必须要有大部分主节点进行投票表决, 但是, 当集群中的大部分主节点都进入失效状态时, 单凭一个两个节点是没有办法将一个节点标记为 FAIL 状态的。

因此, 有了第二个检查条件, 只要集群中的大部分主节点进入了下线状态, 那么集群就可以在不请求这些主节点的意见下, 将某个节点判断为 FAIL 状态, 从而让整个集群停止处理命令请求。

从节点选举

一旦某个主节点进入 FAIL 状态, 如果这个主节点有一个或多个从节点存在, 那么其中一个从节点会被升级为新的主节点, 而其他从节点则会开始对这个新的主节点进行复制。

新的主节点由已下线主节点属下的所有从节点中自行选举产生, 以下是选举的条件:

  • 这个节点是已下线主节点的从节点。
  • 已下线主节点负责处理的槽数量非空。
  • 从节点的数据被认为是可靠的,
    主从节点之间的复制连接(replication link)的断线时长不超过
    节点超时时限 和REDIS_CLUSTER_SLAVE_VALIDITY_MULT常量得出的积。

断线时长 <= node_timeout * REDIS_CLUSTER_SLAVE_VALIDITY_MULT

如果一个从节点满足了以上的所有条件, 那么这个从节点将向集群中的其他主节点发送授权请求, 询问它们, 是否允许自己(从节点)升级为新的主节点。

发送授权请求的从节点要求:
本身是正常运行(不是FALL/PFALL状态)的从节点,所属的主节点出于fall状态,在该下线主节点的所有从节点中ID排序最小

主节点将向从节点返回 FAILOVER_AUTH_GRANTED 授权, 同意从节点的升级要求:
一旦某个从节点在给定的时限内得到大部分主节点的授权, 它就会开始执行以下故障转移操作:

  • 通过 PONG 数据包(packet)告知其他节点, 这个节点现在是主节点了。
  • 通过 PONG 数据包告知其他节点, 这个节点是一个已升级的从节点(promoted slave)。
  • 接管(claiming)所有由已下线主节点负责处理的哈希槽。
  • 显式地向所有节点广播一个 PONG 数据包, 加速其他节点识别这个节点的进度, 而不是等待定时的 PING / PONG 数据包。

所有其他节点都会根据新的主节点对配置进行相应的更新,特别地:

  • 所有被新的主节点接管的槽会被更新。
  • 已下线主节点的所有从节点会察觉到 PROMOTED 标志, 并开始对新的主节点进行复制。
  • 如果已下线的主节点重新回到上线状态, 那么它会察觉到 PROMOTED 标志, 并将自身调整为现任主节点的从节点。

在集群的生命周期中, 如果一个带有 PROMOTED 标识的主节点因为某些原因转变成了从节点, 那么该节点将丢失它所带有的 PROMOTED标识。

1 0
原创粉丝点击