Redis集群模式2-集群模式

redis高可用的集群模式
  • 使用集群,只需要将每个数据库节点的cluster-enable配置打开即可。每个集群中至少需要三个主数据库才能正常运行。即使使用哨兵,redis每个实例也是全量存储,每个redis存储的内容都是完整的数据,浪费内存且有木桶效应。为了最大化利用内存,可以采用集群,就是分布式存储。即每台redis存储不同的内容。集群至少需要3主3从,且每个实例使用不同的配置文件,主从不用配置,集群会自己选。
  • 修改每个实例的配置文件:
  • 集群的运行:
  • 节点的握手方式:在A节点上执行cluster <ip> <port>命令(IP,port是B节点的地址),通过ping-pong方式来确定两个节点的握手。集群的每个数据库都被分为16384个槽,通过cluster addslots命令可以将一个或多个槽分配给节点。只有所有16384个槽被分配完了,当前集群才是上线状态,只要有一个槽没有被分配,集群就是下线状态。
  • 每个节点都有自己的slots数组(clusterNode.slots)来决定自己处理哪些槽,同时节点也会将自己的slots数组告知其他节点,这样每个节点处理的槽的分配在整个集群都是透明的。
  • clusterState结构中的slots数组(clusterState.slots)记录了集群中所有16384个槽的指派信息,slots数组包含16383个项,每个数组项都指向一个clusterNode结构的指针,如果slots[i]指向null,表示i槽尚未指派给任何节点,否则指派给slots[i]指向的节点。
  • clusterState.slots和clusterNode.slots是必须都存在的,clusterState.slots用于花费O(1)的时间复杂度找到某个slot的处理节点,而clusterNode.slots用于向其他节点同步自己的负责信息,直接将clusterNode.slots传播出去即可,不用遍历clusterState.slots。 

Redis集群模式执行命令

客户端发送命令,节点根据key计算属于哪个槽,节点判断自己是否是负责处理这个槽的节点:
  • 是,处理命令
  • 不是,想客户端返回一个MOVED错误,指引客户端转向正确的节点,并再次发送之前想要执行的命令。当前节点判断此key不属于自己的管理槽,会去访问此槽所属节点的clusterNode结构,将ip:port在MOVED错误中返回,客户端接受到错误后会重新发送命令给重定向的节点,集群模式下MOVED错误并不会被打印出来,而单机模式由于不知道该种错误类型会将它直接抛出。
  tips:集群的slots可以通过命令进行重新分配,这个动作不会影响节点的运行,可以热部署,这里不赘述。
 
节点的复制的故障转移
  • 集群是由多个主节点构成,我们可以给主节点指定从节点
  • 从节点会复制主节点,在主节点下线的时候,由其他正在运行的主节点从下线主节点的从节点中,选择一个作为新的主节点,没有被选中的从节点则开始复制新的主节点,下线的主节点重新上线后会成为新的主节点的从节点。
  • 设置从节点的命令CLUSTER REPLICATE <node_id>( 此命令不同于主从集群模式的slave of命令,但是最终执行的还是slave of命令)。
    • 此命令可以将当前节点变为指定<node_id>的从节点。接受命令的节点会在自己的clusterState.nodes字典中找到node_id所对应节点的clusterNode结构,并将自己的clusterState.myself.slaveof指针指向这个结构,以此来记录这个节点正在复制的主节点。
    • 然后节点会修改自己在clusterState.myself.flags中的属性,关闭本来REDIS_NODE_MASTER标示,打开REDIS_NODE_SLAVE标示,表示这个节点已经成为从节点。
    • 最后节点会调用复制代码,这个过程复用了主从集群模式的代码,实际上相当于从节点执行SLAVEOF <master_ip> <master_port>
    • 这种主从关系会同步到集群中所有节点中。
  • 故障检测:
    • 集群中的所有节点都会定时向其他节点发送ping消息,如果对方节点没有在规定时间内返回pong命令,那么当前节点会将它标记为疑似下线状态,当集群中半数以上的主节点认为某个节点已经下线,则将其标记为下线,并推送给集群中的所有节点。
  • 故障转移:
    •   
  • 选举主节点:
    • 主节点的选举类似于选举领头Sentinel的方法非常类似,两者都是基于Raft协议算法的leader选举方法来实现。
    • 集群的配置纪元是一个计数器,初始值为0,当一个从节点开始进行故障转移时,配置纪元加一,在一个配置纪元内,每个处理slots的主节点都只有一次投票机会,他们只会投票给自己收到的第一个需要投票的字节点发送的信息,在一个配置纪元内,只有当某个从节点获得半数以上的投票,才能成为主节点,否则进入下一个配置纪元重新选举。 
posted @ 2020-01-29 16:10  lastcy  阅读(396)  评论(0编辑  收藏  举报