引言

Redis集群通过分片进行数据共享,并且提供复制和故障转移功能。
在学习主从复制和哨兵机制的时候,知道他们一个重要的缺点,动态扩容麻烦。
Redis集群通过分片可以很轻松解决扩容问题,增加节点的时候,
只需重新分片,相关槽转移即可,不影响redis集群对外提供服务。

1、节点

节点通过CLUSTER MEET命令加入到集群,并通过Gossip协议传播加入集群的节点的信息,最终所有的节点都保存集群中所有节点的信息。
Gossip协议是P2P网络的核心技术,也叫流行病协议,具有扩展性、容错、去中心化、最终一致性、简单等特点。
传播过程是由其中一个节点发起,随机选择周围几个节点散播消息,收到消息的节点也重复该过程,最终所有节点都收到消息,适合实时性不高的系统。

2、槽指派

Redis集群通过分片的方式保存数据库中的键值对,整个集群被分为16384个槽(slot)。
数据通过CRC16计算hash,再对16384取模,获取到当前数据的目标槽,最后定位到负责该槽的节点信息。
每个节点都存储了其他节点的槽信息,所以集群模式的时候,只需要连接一个节点即可。
当执行命令的时候,如果当前数据正好在此节点上,则执行命令,否则当前节点返回MOVED错误,并带有此数据对应槽的相应节点信息给客户端,之后客户端转向到相应的数据槽节点执行命令。

3、重新分片

当集群中新增加一个节点的时候,会执行槽的重新分配,也就会发生重新分片。在这个过程中,Redis集群不会停止服务,依然对外提供服务。

3.1、原理

假设将一个节点的一部分槽转移到新增节点中。首先获取源节点转移槽所负责的所有键,将这些键转移到新节点即可。

在进行槽转移的过程中,有些数据在源节点,有些数据在新的节点,当有客户请求的时候,会先在源节点查找,如果数据不在,则返回客户ASK错误并指引客户转向新的节点执行命令。

4、复制和故障转移

Redis集群中的节点分为主节点与从节点,主节点负责处理槽,从节点负责复制主节点。
如果其中一个主节点下线,其下属从节点之一会被其他主节点选为新的主节点,下线的主节点的其他从节点会复制新的主节点,
下线的主节点上线时会成为新的主节点的从节点。

4.1、故障检测

当一个节点发现另一个节点没有在规定时间内回复PING消息时,会将其标记为疑似下线,之后其他节点也会检测这个疑似下线的节点,超过半数确定疑似下线时,标记为下线。

4.2、故障转移步骤

来源于《Redis设计与实现》

  • 主节点的下属从节点会有个成为主节点
  • 新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己,在这期间有命令过来时,碰巧数据在这台主节点上,则会受到影响。
  • 新的主节点向集群中广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原本由已下线节点负责处理的槽。
  • 新的主节点开始接受和自己负责处理的槽有关的命令请求,故障转移完成。

4.3、主节点选举

这里的选举与哨兵选举很类似,因为都是根据raft算法而来。
下面介绍一下步骤:

  • 集群的配置纪元是一个自增计数器,相当于投票的轮数。
  • 在每一个配置纪元内,集群中的每个负责处理槽的主节点都只有一次投票的机会,根据先来后到原则,第一个向主节点要求投票的从节点将获得选票。
  • 从节点获得选票数量大于集群中主节点半数之后,从节点成为主节点。
  • 否则进入下一个配置纪元,继续选举。

tencent.jpg