节点
Redis集群由多个节点组成,每个节点都由一个clusterNode结构来表示节点的状态,同时每个节点有一个clusterLink结构的link属性保存连接节点的有关信息,并且每个节点有一个clusterState结构来保存集群目前所处的状态。
槽指派
Redis集群通过分片的方式保存数据库中的键值对,集群的整个数据库被分成16384个槽,数据库中的每个键都属于这16384槽的其中一个,集群中的每个节点可以处理0个或最多16384个槽,只有当数据库中的16384个槽都有节点在处理的时候,集群才处于上线状态。通过CLUSTER ADDSLOTS命令给节点指派相应的槽
在集群中执行命令
当客户端向Redis节点发送命令的时候,节点会计算键属于哪个槽(可以通过CLUSTER KEYSLOT查看),如果属于自己处理的槽则执行命令,否则向客户端发送MOVED错误让客户端重定向到处理该槽的节点。对于clusterState结构中还会使用跳跃表来记录槽和键的关系,跳跃表中的分支代表一个槽号,每个节点的成员都是一个数据库键。
重新分片
Redis集群重新分片操作可以将任意数量已经指派给某个节点的槽改为指派给另一个节点,并且相关槽所属的键值对才会从源节点被移动到目标节点。
ASK错误
重新分片期间如果收到客户端的命令,需要进行如下操作:
image.png
clusterState结构的importing_slots_from数组记录了当期那节点正在从其他节点导入的槽。
clusterState结构的migrating_slots_to数组记录了当前节点正在迁移至其他节点的槽。
所以,如果收到数据库命令的节点没有相应的键,会检查自己的migrating_slots_to数组,看看是否已经把键转移给了其他节点。
关于ASK错误和MOVED错误的区别:
MOVED错误类似永久重定向,ASK错误类似临时重定向(只是个一次性标识)
复制与故障转移
集群使用CLUSTER REPLICATE设置从节点,和单机Redis服务器的复制功能使用相同代码。
集群中的各节点定期会互相发送消息,如果没有接收到某个主节点X的响应,则X会被认为疑似下线,倘若网络中超过半数的节点都认为某个主节点X疑似下线,则这个主节点X被标记为已下线,同时广播该X节点已下线的消息。
一旦某个主节点被判定为下线状态时,需要对相应的从节点进行故障转移:
从下线主节点的从节点里面选择一个执行SLAVE NO ONE命令,使其成为主节点,然后将已下线主节点的槽指派指派给自己,并向集群广播消息,处理后序相关槽的请求。
对于选举新的主节点,和哨兵选举领头节点的方法十分相似,都是基于Raft算法的领头选举方法来实现的。
消息
集群中的各个节点可以互相收发消息,消息由消息头clusterMsg和消息正文clusterMsgData组成,共有MEET,PING,PONG,FAIL,PUBLISH五种消息。
image.png












网友评论