《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 条评论
登录 后参与评论

相关文章

来自专栏有趣的Python

慕课网-c语言入门-学习笔记

个人整理,学习自用。课程内容by慕课网。 c语言入门 C语言一经出现就以其功能丰富、表达能力强、灵活方便、应用面广等特点迅速在全世界普及和推广。C语言不但执行效...

4226
来自专栏深度学习入门与实践

【原】Learning Spark (Python版) 学习笔记(二)----键值对、数据读取与保存、共享特性

  本来应该上周更新的,结果碰上五一,懒癌发作,就推迟了 = =。以后还是要按时完成任务。废话不多说,第四章-第六章主要讲了三个内容:键值对、数据读取与保存与S...

3278
来自专栏简书专栏

Python入门

多媒体应用、WEB开发、网络爬虫、人工智能与机器学习、数据分析处理、服务器运维及其他小工具 知乎链接:用python做一些有趣的事情

823
来自专栏算法channel

MySQL|索引背后

01 索引 以MySQL中的索引为例子总结。 数据库查询是数据库的最主要功能之一,实现高效的查询速度一定是MySQL非常关心的事情。 索引(Index)正是帮...

4248
来自专栏C/C++基础

C++嵌套类与局部类

定义嵌套类的初衷是建立仅供某个类的成员函数使用的类类型。目的在于隐藏类名,减少全局的标识符,从而限制用户能否使用该类建立对象。这样可以提高类的抽象能力,并且强调...

631
来自专栏企鹅号快讯

Java初学者的30个常见问题

1.2 基本数据类型 Q. 为什么 -0/3 结果是 0,而 -0.0/3.0 结果是 -0.0?(注意后边的结果0带负号) A. 在Java里,整数是用补码...

1765
来自专栏yukong的小专栏

【SpringBoot2.0系列10】SpringBoot之@Scheduled任务调度实现结语

相信大家在实际工作场景中会遇到这样的情况,系统之间存在数据交换,为了不影响正常服务器运,我们需要在每天的凌晨来进行数据交换,但是让程序每天凌晨自动执行呢,下面带...

1021
来自专栏小樱的经验随笔

彻底搞定C语言指针(精华版)

1.语言中变量的实质 要理解C指针,我认为一定要理解C中“变量”的存储实质, 所以我就从“变量”这个东西开始讲起吧! 先来理解理解内存空间吧!请看下图: ...

3143
来自专栏老司机的技术博客

golang学习笔记3:常量与变量

常量使用关键字 const 定义,用于存储不会改变的数据。 存储在常量中的数据类型只可以是布尔型、数字型(整数型、浮点型和复数)和字符串型。 常量的定义格式: ...

601
来自专栏恰同学骚年

剑指Offer面试题:14.链表的倒数第k个节点

PS:这是一道出境率极高的题目,记得去年参加校园招聘时我看到了3次,但是每次写的都不完善。

724

扫码关注云+社区