Redis集群是Redis提供的分布式数据库方案,集群通过分片来进行数据共享,并提供复制和故障转移功能。
节点握手
一个redis集群通常是由多个节点组成,刚开始的时候,每隔节点都是相互独立的,它们都处于一个只包含自己的集群当中,要组建一个真正可工作的集群,我们必须将多个独立的节点连接起来,构成一个保护多个节点的集群。连接各个节点的工作由CLUSTER MEET命令完成。
节点握手过程:
1、节点A会为节点B创建一个clusterNode结构,并将该结构添加到自己的clusterState.nodes字典里面。
2、节点A根据CLUSTER MEET命令给定的ip和端口向节点B发送MEET消息。
3、如果顺利,及诶单B将接收到节点A发送的MEET消息,节点B会为节点A创建一个clusterNode结构,并将结构添加到自己的clusterState.nodes字典里面。
4、之后,节点B将向节点A返回一条PONG消息。
5、如果顺利,节点A将接收到节点B返回的PONG消息,通过这条PONG消息节点A可以知道B已经成功接收到自己的MEET消息。
6、之后节点A向节点B返回一条PING消息。
7、如果一切顺利,节点B将接收到节点A返回的PING消息,通过这条PING消息节点B可以知道节点A已经成功接收到了自己返回的PONG消息,握手完成。
之后,节点A会将节点B的信息头弄个Gossip协议传播给集群中的其他节点,让其他节点也与节点B进行握手,最终,经过一段时间之后,节点B会被集群中所有节点认识。
槽指派
redis集群通过分片的方式来保存数据库中的键值对:集群中的整个数据库被分为16384个槽slot.
通过向节点发送CLUSTER ADDSLOTS命令,可以将一个或多个槽指派给节点负责。
在集群模式下,可以通过 CLUSTER KEYSLOT 命令可以查看一个给定的键属于哪个槽。
节点复制
redis集群中的节点分为主节点master和从节点slave,其中主节点主要用于处理槽,而从节点则用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求。
通过向一个节点发送 CLUSTER REPLICATE <node_id> 可以让接收命令的节点称为node_id所指定节点的从节点,并开始对主节点进行复制。
一个节点成为从节点,并开始复制某个主节点,这一信息会通过消息发送给集群中的其他节点,最终集群中的所有节点都会知道某个从节点正在复制某个主节点。
故障检测
1、集群中的每个节点都会定期的向集群中的其他节点发送PING消息,以此来检测对方是否在线。
2、如果接收方没有在规定的时间内向发送PING消息的节点返回PONG消息,那么发送PING消息的节点就会将接收PING消息的节点标记为疑似下线。
3、集群中的各个节点会通过相互发送消息的方式来交换集群中各个节点的状态信息,例如:某个节点是处于在线状态、疑似下线PFAIL,还是已下线状态FAIL。
当一个节点A通过消息得知主节点B认为主节点B认为主节点C进入了疑似下线状态时,主节点A会在自己的
clusterState.nodes字典中找到主节点C所对应的clusterNode结构,并将主节点B的下线报告添加到
clusterNode结构的fail_reports链表里面,这个链表记录了所有其他节点对该节点的下线报告。
4、如果在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线FAIL,将主节点x标记为已下线的节点会向集群广播一条关于主节点x的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点x标记为已下线。
故障转移
当一个从节点发现自己正在复制的主节点进入了已下线状态时,从节点将开始对下线节点进行故障转移。
1、选举新的主节点
复制下线主节点的所有从节点里面,会有一个从节点被选中作为新的主节点
2、被选中的从节点会执行SLAVEOF no one命令,称为新的主节点。
3、新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽指派给自己。
4、新的主节点向集群广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即致电这个节点已经由从节点变成了主节点,并且这个主节点已经接管了原本已下线节点负责处理的槽。
5、新的主节点开始接收和自己负责处理的槽有关的命令请求,故障转移完成。
集群中的消息
- MEET 消息:通过CLUSTER MEET命令,请求接收者加入到发送者当前所处的集群里面。
- PING消息:检测集群节点是否在线
- PONG消息:对发送MEET或者PING消息的发送者返回PONG消息以确认消息收到。另外一个节点也可以向集群广播自己的PONG消息来让集群中的其他节点立即刷新关于这个节点的认识。
- FAIL消息:当一个主节点A判断另一个主节点B进入FAIL状态时,节点A会向集群广播一条关于节点B的FAIL消息,所有接收到这条消息的节点会立即将节点B标记为已下线。
- PUBLISH消息:当节点接收到一个PUBLISH命令时,节点会执行这个命令并向集群广播一条PUBLISH消息,所有接收到这条PUBLISH消息的节点都会执行相同的PUBLISH命令。
以上是今天总结的关于redis集群中槽指派,集群通信,主从复制,故障转移的相关知识。