Redis 集群提纲
CLUSTER MEET 命令
通过向节点A发送CLUSTER MEET命令,客户端可以让接收命令的节点A将另一个节点B添加到节点A当前所在的集群里面。
NodeA会为NodeB 创建一个clusterNode结构,并将该结构添加到自己的clusterState.Nodes字典里面。
之后,节点A将根据CLUSTER MEET命令给定的IP地址和端口号,向NodeB发送一条MEET消息
NodeB收到NodeA发送的MEET消息,NodeB会为NodeA创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典里面。
之后,NodeB向NodeA返回一条PONG消息。
NodeA接收到NodeB返回的PONG消息,通过这条PONG消息NodeA可以知道NodeB已经成功接收到了自己发送的MEET消息。
NodeA向NodeB返回一条PING消息。
NodeB接收到NodeA的PING消息,通过这条PING消息NodeB可以知道NodeA成功接收了自己返回的PONG消息。握手完成。
槽指派
redis集群通过分片的方式来保存数据库中的键值对;集群的真个数据库被分为16384个槽位,集群中的每个节点可以处理0-16384个槽位。
当数据库中的16384个槽位都有节点在处理时,集群处于上线状态。相反地,如果数据库中有任何一个槽位没有得到处理,那么集群处于下线状态。
通过CLUSTER ADDSLOTS命令,指派一个或者多个槽位。
在集群中执行命令
当客户端向节点发送与数据库键有关的命令时,接受命令的节点会计算出命令要处理的数据库键属于哪个槽,并检查这个槽是否指派给了自己。
如果键所在的槽正好就指派给了当前节点,那么节点直接执行这个命令。
如果键所在的槽没有指派给当前节点,那么节点会向客户端返回一个MOVED错误,指引客户端转向至正确的节点,并再次发送想要执行的命令。
计算键属于哪个槽
使用 CRC16(key) & 16383来计算key属于哪个槽
重新分片
Redis集群重新分片操作可以将任意数量已经指派给某个节点的槽改为指派另一个节点,并且相关槽所属的键值对也会从源节点被挪动到目标节点。
Redis集群的重新分片操作是由Redis的集群管理软件redis-trib负责执行的。
复制
Redis集群中的节点分为主节点(master)和从节点(slave),其中主节点用于处理槽,而从节点则用于复制某个主节点,并在被复制的主节点下线时,代替下线 主节点继续处理命令请求。
通过向一个节点发送CLUSTER REPLICATE
集群中的每个节点都会定期的向集群中的其他节点发送PING消息,以此来检测对方是否在线。
在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标志为已下线(FAIL),将主节点x标记为已下线的节点会向集群 广播一条关于主节点x的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点x标记为已下线。
故障转移
当一个从节点发现自己正在复制的主节点进入了已下线状态时,从节点将开始对下线的主节点进行故障转移
复制下线主节点的所有从节点里面,会有一个从节点被选中。
被选中的从节点会执行SLAVEOF no one命令,成为新的主节点。
新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部都指派给自己。
新的主节点向集群里广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原来已下线节点负责的槽。
新的主节点开始接受和自己负责处理的槽相关的命令请求,故障转已完成。
选举新的主节点
选举新的主节点方法:
集群的配置纪元是一个自增计数器,它的初始值是0.
当集群里的某个节点开始一次故障转移操作时,集群配置纪元的值会自增1
对于每个配置纪元,集群里每个负责处理槽位的主节点都有一次投票的机会,而第一个向主节点要求投票的从节点将获得主节点的投票。
当从节点发现自己正在复制的主节点进入已下线状态时,从节点会向集群广播一条CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST消息,要求所有收到这条消息、并且具有 投票权的主节点向这个从节点投票。
如果一个主节点具有投票权,并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点 支持从节点成为新的主节点。
每个参与选举的从节点都会收到CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持。
如果集群里有N个具有投票权的主节点,每个具有投票权的主节点只能投一次票,所以如果有N个主节点进行投票,那么具有大于等于N/2+1张支持票的从节点只会有一个看,这确保了 新的主节点只会有一个。
如果在一个配置纪元里面没有从节点能收集到足够多的支持票,那么集群进入一个新的配置纪元,并再次进行选举,知道选出新的主节点为止。