集群(cluster)是Redis提供的分布式数据库解决方案,集群通过分片(sharding)来进行数据共享,并提供数据复制(replication)和故障转移(failover)等功能。下面介绍下Cluster的执行流程。
Redis服务器在启动时,会根据cluster-enabled配置决定是否开启服务器的集群模式。如果未开启,就进入stand alone模式,以普通单机Redis方式运行。否则进入集群模式。
一个Redis集群通常由多个节点(node)组成。在初始化时,每个node都是相互独立的,它们都处于一个只包含自己的集群当中。要想组成一个真正可用的集群,必须将多个独立的节点连接起来。
向一个node发送CLUSTER MEET命令,可以让node与指定的节点进行握手,握手成功后,指定的节点就加入到node所在的集群中。
新的节点加入集群后。node会通过Gossip协议传播给集群中的其他节点,让其他节点也与新加入的节点握手。最终经过一段时间后,集群中的所有节点就建立起了连接。
**Redis通过数据分片的方式保存数据库中的键值对:整个数据库被分为16384个槽(slot),数据库中的每个键都位于这16384个槽中的一个,集群中的每个节点都可以处理0~16384个槽。**可以通过命令为每个节点分配指定的槽位。
在对数据库中的16384个槽都分配成功了之后,集群就进入上线状态,就可以正常接收客户端命令提供服务了。
当客户端向集群中的节点发送key相关操作的命令时,接收命令的节点会进行如下操作:
Redis集群可以通过重新分片操作,将任意数量的已经指派给某个节点(源节点)的槽改为指派给另一个节点(目标节点),并且槽位上所属的所有键值对也会一并被移动过去。
重新分片操作可以在线执行,在重新分片操作执行过程中,集群不需要下线,并且源节点和目标节点都可以继续处理客户端请求。
在执行重新分片的过程中,可能存在这样一种情况:在迁移某个槽位上的数据时,一部分数据已经被迁移到了目标节点,而还有一部分数据仍然在源节点上未迁移完成。此时客户端如果向源节点发送请求,要对这个槽位上的数据进行处理,则会进行如下的操作:
集群中的节点分为主节点(master)和从节点(slave)。主节点用于处理槽相关的操作,而从节点则用于复制主节点,并在主节点下线时,选举出一个新的主节点,代替下线的主节点继续处理命令请求。
集群中的每个节点都会定期向集群中的其他节点发送PING消息,以此来检测对方的在线状态。如果接收PING消息的节点没有在规定时间内返回PONG响应,则发送PING消息的节点会将接收PONG消息的节点标记为疑似下线(probable fail, PFAIL)状态。
集群中的每个节点都会通过相互发送消息的方式,来交换集群中各个节点的状态信息,例如一个节点是在线状态、疑似下线状态(PFAIL)还是已下线状态(FAIL)。
如果一个集群中,半数以上的处理槽的主节点都认为一个主节点处于PFAIL状态,那么这个主节点就会被标记为已下线状态(FAIL),并将这个主节点下线的消息在集群中进行广播,所有接受到这条消息的节点都会立即将其标记为FAIL状态。
当一个从节点发现它复制的主节点进入下线状态时,那么从节点就会对已下线的主节点进行故障转移,下面是执行故障转移的步骤:
集群中的各个节点都是通过消息来彼此通信的。发送消息的节点成为sender,接收消息的节点成为receiver。节点的消息类型主要有一下五种: