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

相关文章

来自专栏Java后端技术栈

Java多线程编程-(13)-从volatile和synchronized的底层实现原理看Java虚拟机对锁优化所做的努力

对于Java来说我们知道,Java代码首先会编译成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上进行执行。

961
来自专栏跨界架构师

C#中的原子操作Interlocked,你真的了解吗?

  这个标题起的有点标题党的嫌疑[捂脸],这个事情的原委是这样的,有个Web API的站点在本地使用Release模式Run的时候出现问题,但是使用Debug模...

1253
来自专栏IT技术精选文摘

Java Instrument 功能使用及原理

1943
来自专栏Java开发者杂谈

Spring @Transactional踩坑记

@Transactional踩坑记 总述 ​ Spring在1.2引入@Transactional注解, 该注解的引入使得我们可以简单地通过在方法或者类上添加@...

8547
来自专栏程序猿DD

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

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

1437
来自专栏Golang语言社区

Go- Buffer Channel- Select-基础理解

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

4628
来自专栏精讲JAVA

java面试线程必备知识点,怼死面试官,从我做起

内存屏障:限制命令操作顺序,有LoadLoad、LoadStore、LoadStore、StroreStreo四种屏障

1554
来自专栏芋道源码1024

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

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

3618
来自专栏Java技术栈

Java 内存模型 JMM 详解!

1942
来自专栏余林丰

Struts2中的JSON问题——后台返回JSON字符串到前台

  最近做一个项目遇到一个比较棘手的问题,项目后台采用struts2+Hibernate3+Spring3,前台采用ExtJs4。笔者目前仍是一名大二学生吗,后...

2406

扫码关注云+社区

领取腾讯云代金券