tips
- redis集群中的从节点既不支持写操作也不支持读操作,只是做个备份,当主节点挂了之后,转换成主节点顶上去,实现高可用。
- 在redis集群中,多个节点分布在不同的机器上的,这个时候它会把不同机器上的节点分配成主从关系,例如:节点A和节点B在一台机器上,节点C和节点D在一台机器上,这个时候会把节点A和节点D分配成一对主从,节点C和节点B分配成一对主从,这样做主要是为了某一台机器挂了,整个Redis集群还能对外提供服务,实现高可用。
集群原理
关键字:槽位,槽位定位,槽位映射表,重定位
- 集群的所有数据会分为16384个槽位(slots),每个节点负责一部分槽位;
- 客户端会使用crc16算法进行hash运算,然后对16384取模来得到具体的槽位;
- 客户端根据自己的槽位映射表缓存来选择对应的节点进行通信;
- 对应的节点发现指令key所在的槽位不归自己管理时,会向客户端发送一条特殊命令,并携带正确的节点地址信息,然后客户端会将正确的节点地址信息更新到自己槽位映射表中去。
集群选举
关键字:选举周期,票数过半,ack响应,延迟ack请求
当master节点挂掉之后,由于存在多个slave节点,要从多个slave节点中确定出一个master节点,这个时候就需要进行选举了,选举的过程:
- slave发现自己的master的状态变成了FAIL,经过一段延迟(DELAY)之后,就会广播FAILOVER_AUTH_REQUEST消息,这里的DELAY有一个计算格式:
- DELAY=500ms + random(0~500ms) + SLAVE_RANK * 1000ms,SLAVE_RANK 表示slave复制数据总量的rank,这个值越小就说明已复制的数据越新,理论上这个slave就越有可能成为master;
- 其他节点收到FAILOVER_AUTH_REQUEST消息之后,只有master会做出响应,master首先会检查该消息的有效性,然后做出响应FAILOVER_AUTH_ACK;
- 如果一个slave收到了超过半数的master的FAILOVER_AUTH_ACK,它就会自动成为master,这也就是集群至少需要三个主节点的原因:如果只有两个主节点的话,其中一个主节点挂了,另外只有一个主节点完成不了选举;
- 成为主节点的slave广播Pong消息来通知其他节点我成为了master。
集群脑裂
关键字:网络抖动,两个master,数据丢失,min-slaves-to-write 1。
- 因为一个master的网络问题,导致slave和其他节点以为这个master挂掉了,这个时候集群会选举其中一个slave成为master,但是实际上原来的master是存活的,这个时候就会存在两个master,出现了脑裂现象,且客户端还是连着原来的master在写入数据;
- 当网络恢复之后,集群以为原来的master复活了,会将它作为一个slave添加到集群中,成为slave的时候会复制master上的数据,这个时候就会把发生脑裂之后的数据全部覆盖掉了,造成大量的数据丢失。
- 为了防止数据丢失,可以添加配置min-slaves-to-write 1,它的含义是当你写入数据时,不仅仅是写入到master节点,还必须至少要同步到一个slave节点才会给你返回数据写入成功的结果,当发生脑裂时,因为原来的master节点没有slave节点同步,会拒绝客户端的数据写入,新版本的这个配置改成了min-replicas-to-write 1;
- 这个配置很显然会带来可用性的问题:当我们只有一个slave,且slave挂掉时,整个节点就不可用了。这个就涉及到著名的CAP理论了,只能选择其中的CP或者AP,当你选择了可用性(AP)时,就必须要接受数据不一致性(CP)了,这个就需要根据实际项目的需求来选择了。