《Redis设计与实现》读书笔记(三十) ——Redis集群节点复制与故障转移

《Redis设计与实现》读书笔记(三十) ——Redis集群节点复制与故障转移

(原创内容,转载请注明来源,谢谢)

1、概述

redis集群的节点,分为主节点和从节点,主节点负责处理槽,从节点复制主节点的数据,并且在复制的主节点下线时,替代主节点。集群中可以有多个主节点。

如上图,7000~7003都是主节点,7004和7005作为从节点复制7000节点,当7000下线则7004和7005有一个会被选为主节点,替代7000。

例如7004被选为主节点,则7004替代7000管理7000原先负责的槽,而7005则复制7004。当7000重新上线,也会成为7004的从节点。

2、设置从节点

命令如下:clusterreplicate <node_id>,则将当前节点设置为node_id的从节点,并对其进行复制。

设置过程如下:

1)接收到该命令的节点,会先 在自身结构的clusterState结构体的nodes数组中,找到对应的节点的clusterNode,使用slaveof属性来记录主节点。

         structclusterNode{
         //….其他内容
         struct clusterNode *slaveof;
         };

2)修改自身的flags属性,去掉redis_node_master,加上redis_node_slave,表示变成从属节点。

3)调用复制的代码,根据上述slaveof保存的主节点的信息中的ip和端口号,去获取数据。

因此,cluster replicate命令等同于单机情况下的主从复制中的slaveof命令。

命令执行完毕后,该节点会在集群中发送消息给其他节点告知。

其他节点都会在各自保存主节点结构的结构体中,对应的numslaves属性记录该节点的从节点个数,以及slaves数组,该数组每个属性记录的是指向该节点从节点的clusterNode指针。

struct clusterNode{
         //….其他内容
         int numslaves;
         struct clusterNode **slaves;
};

3、故障检测

每个节点都会定期给其他节点发送ping信息,以此检测对方是否在线,如果在规定时间内ping没有得到返回,则认为疑似下线。如果节点认为某个节点疑似下线,就会在保存那个节点的clusterNode结构体中,flags属性加上redis_node_pfail属性。

每个节点自身的clusterNode结构体中,都有一个属性是fail_reports,该属性是一个链表,用于记录其他节点的下线报告。

         structclusterNode{
         //….其他内容
         list *fail_reports;
         };

list中的每一个元素,都是一个clusterNodeFailReport结构体,结构如下:

struct clusterNodeFailReport{
   struct clusterNode *node;//指向下线节点的指针
   mstime_t time;//最后一次从node节点收到的下线报告时间,为了节约空间,如果与当前时间相差太久,该结构体会被删除
};

在一个集群中,半数以上的节点认为某个节点疑似下线,则该节点被认定为已下线。并且会广播给集群的所有节点。

4、故障转移

当一个从节点发现自己正在复制的主节点已下线状态,则会开始进行故障转移。步骤如下:

1)复制下线主节点的所有从节点,有一个被选中。

2)被选中的从节点,执行slaveofno one命令,变成主节点。

3)新主节点撤销对原主节点的槽指派,并指派给自己。

4)新主节点向集群发一条pong信息,告知集群其已经变成主节点。

5)新主节点开始处理槽有关的工作,故障转移完成。

5、选举新主节点方式

新主节点是通过选举产生,方法如下:

1)集群配置纪元是一个计数器,默认是0。

2)集群中进行一次故障转移,增1。

3)每个配置纪元期间,集群中负责处理槽的主节点都有一次投票的机会,其会投票给最先要求其投票给节点的节点。

4)当从节点发现主节点下线,会向集群广播clustermsg_type_failover_auth_request信息,要求所有接收到该信息并且具备投票权的主节点,给该从节点投票。

5)如果主节点具备投票权,并且尚未投给其他节点,则会对该节点回复clustermsg_type_failover_auth_ack,告知其投票。

6)每个参选的主节点都会接受clustermsg_type_failover_auth_ack回复,并记录支持的数量。

7)当集群有n个主节点,则从节点获得的票数大于或等于1+n/2时(即过半),则成为新的主节点。

8)如果一个配置纪元内,没有节点票数满足要求,则进入一个新的配置纪元,重新上述步骤。

主节点的选取方式和选取领头sentinel的方式很相似,都是raft算法的领头选举。

——written by linhxx 2017.09.18

原文发布于微信公众号 - 决胜机器学习(phpthinker)

原文发表时间:2017-09-18

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Golang语言社区

Go- Buffer Channel- Select-基础理解

这篇主要讲Select这个有用的关键字用来监听管道顺带讲下带缓冲的Channel 带缓冲的Channel Channel是可以带有缓冲的 c := make(c...

4308
来自专栏NetCore

Do You Know?Url Path MaxLength Limit -- 你或许以后会遇到的一个问题

最近一直在学习Asp.Net MVC,大家都知道可以用System.Web.Routing来解析一段Url,然后到达我们Route规则定下的一个Controll...

1838
来自专栏Java技术栈

Java 内存模型 JMM 详解!

1622
来自专栏眯眯眼猫头鹰的小树杈

深入理解 依赖注入

相信所有面试java开发的童鞋一定都被问到过是否使用过Spring,是否了解其IOC容器,为什么不直接使用工厂模式,以及究竟IOC和DI区别在于哪里这种问题。今...

661
来自专栏chenssy

【死磕Java并发】-----深入分析synchronized的实现原理

记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予...

1463
来自专栏码洞

依赖注入不是Java的专利,Golang也有

笔者在使用Golang的时候就发现构建系统依赖树非常繁琐,New了很多对象,又手工代码将它们拼接起来,写了一堆非常冗繁的代码。然后就开始想,要是Golang像J...

771
来自专栏Seebug漏洞平台

从补丁到漏洞分析——记一次joomla漏洞应急

作者:LoRexxar'@知道创宇404实验室 2018年1月30日,joomla更新了3.8.4版本,这次更新修复了4个安全漏洞,以及上百个bug修复。 ht...

33912
来自专栏玄魂工作室

CTF实战28 Windows缓冲区溢出

该培训中提及的技术只适用于合法CTF比赛和有合法授权的渗透测试,请勿用于其他非法用途,如用作其他非法用途与本文作者无关

1201
来自专栏程序猿DD

死磕Java并发:深入分析synchronized的实现原理

记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized。对于当时的我们来说,synchronized是如此的神奇且强大。我们赋予它一个名字...

1257
来自专栏沈唁志

ThinkPHP5框架与ThinkPHP3.2的对比区别

4252

扫码关注云+社区