redis集群中的节点分为主节点和从节点,其中主节点用于处理槽,而从节点用于复制某个主节点,并在被复制的主节点下线时,代替下线主节点继续处理命令请求。
向一个节点发送命令:CLUSTER REPLICATE ,可以让接受命令的节点成为node_id所指定节点的从节点,并开始对主节点进行复制,将自己clusterNode 结构中的slaveof字段指向node_id的clusterNode结构。接下来集群中的所有节点都会在代表主节点的clusterNode结构的slaves属性和numslaves属性中记录正在复制这个主节点的从节点名单。
集群中的每个节点都会定期向集群中的其他节点发送PING消息,以此来检测对方是否在线,如果接收PING消息的节点没有在规定的时间内,向发送PING消息的节点返回消息,那么发送方会将接收方的节点标记为疑似下线。
当一个主节点A通过消息得知主节点B认为主节点C进入了疑似下线状态时,主节点A会在自己clusterState.nodes字典中找到主节点C所对应的的clusterNode结构,将主节点B的下线报告添加到clusterNode结构的fail_reports链表里面
如果在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线,将主节点x标记为已下线的节点会向集群广播一条关于主节点x的FAIL消息
当一个从节点发现自己正在复制的主节点进入了已下线状态时,从节点将开始对下线主节点进行故障转移:
1. 复制下线主节点的所有从节点里面,会有一个从节点被选中,并成为新的主节点,(对于每一个epoch,集群里每个负责处理槽的主节点都有一次投票的机会,而第一个想主节点要求投票的从节点将获得主节点的投片)
2. 新主节点接管老主节点的槽,并向集群广播一条PONG消息,让其他节点意识到这台主节点已经接管了原来下线的主节点
消息
集群当中的各个节点通过发送和接收消息来进行通信,节点发送的消息主要有以下五种:
1. MEET:请求接受者加入到发送者当前所属的集群里面
2. PING:集群里的每个节点默认每隔一秒就会从以直接点列表中随机选出五个节点,然后对这五个节点中最长没有时间发送过PING消息的节点发送PING消息,以此来检测被选中的节点是否在线。
3. PONG:当接收者收到发送者发来的MEET或者PING消息时,接收者会返回一条PONG消息。另外,一个节点可以通过向集群当中光爆PONG消息来让集群中的其他节点立即刷新对这个节点的认识。
4. FAIL:当一个主节点A判断另一个主节点B已经进入FAIL状态时,节点A会向集群广播一条关于节点B的FAIL消息,所有收到这条消息的节点都会立即将节点B标记为已下线
5. PUBLISH:当节点接收到一个PUBLISH命令时,会执行这个命令,并向集群广播一条PUBLISH消息,所有接收到这条PUBLISH消息的节点都会执行相同的PUBLISH命令
节点发送的所有消息都由一个消息头包裹,消息头除了包含消息正文之外,还记录了消息发送者自身的一些信息,
-
typedef struct {
-
char sig[4]; /* Siganture "RCmb" (Redis Cluster message bus). */
-
uint32_t totlen; /* Total length of this message */
-
uint16_t ver; /* Protocol version, currently set to 1. */
-
uint16_t port; /* TCP base port number. */
-
uint16_t type; /* Message type */
-
uint16_t count; /* Only used for some kind of messages. */
-
uint64_t currentEpoch; /* The epoch accordingly to the sending node. */
-
uint64_t configEpoch; /* The config epoch if it's a master, or the last
-
epoch advertised by its master if it is a
-
slave. */
-
uint64_t offset; /* Master replication offset if node is a master or
-
processed replication offset if node is a slave. */
-
char sender[CLUSTER_NAMELEN]; /* Name of the sender node */
-
unsigned char myslots[CLUSTER_SLOTS/8];
-
char slaveof[CLUSTER_NAMELEN];
-
char myip[NET_IP_STR_LEN]; /* Sender IP, if not all zeroed. */
-
char notused1[34]; /* 34 bytes reserved for future usage. */
-
uint16_t cport; /* Sender TCP cluster bus port */
-
uint16_t flags; /* Sender node flags */
-
unsigned char state; /* Cluster state from the POV of the sender */
-
unsigned char mflags[3]; /* Message flags: CLUSTERMSG_FLAG[012]_... */
-
union clusterMsgData data;
-
} clusterMsg;
其中data字段指向联合clusterMsgData,这个联合就是消息的正文
-
union clusterMsgData {
-
/* PING, MEET and PONG */
-
struct {
-
/* Array of N clusterMsgDataGossip structures */
-
clusterMsgDataGossip gossip[1];
-
} ping;
-
-
/* FAIL */
-
struct {
-
clusterMsgDataFail about;
-
} fail;
-
-
/* PUBLISH */
-
struct {
-
clusterMsgDataPublish msg;
-
} publish;
-
-
/* UPDATE */
-
struct {
-
clusterMsgDataUpdate nodecfg;
-
} update;
-
};
发送PUBLISH 消息的命令是PUBLISH ,接收到命令的节点不仅会先gchannel频道发送消息message,它还会向集群广播一条PUBLISH 消息,所有接收到这条PUBLISH消息的节点都会向channel频道发送message消息
阅读(3944) | 评论(0) | 转发(0) |