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

相关文章

来自专栏落花落雨不落叶

jquery实现轮播图

30011
来自专栏游戏开发那些事

【随笔】关于算法竞赛中使用文件输入输出和文件名的规定等问题

算法竞赛对文件名有着严格的规定,包括程序名和输入输出文件名,不要使用绝对路径或者相对路径。

873
来自专栏数据结构与算法

SPOJ1716 GSS3(线段树)

431
来自专栏Python小屋

1000道Python题库系列分享13(22道填空题)

592
来自专栏安恒网络空间安全讲武堂

SharifCTF 2018 Crypto writeup

本文作者:HeartSky 之前的SharifCTF,其中密码学部分有许多有意思的题目,因此来分享下相关解题过程。 0x01 DES See known_p...

4477
来自专栏知识分享

Duplicate id @+id/imageView, already defined earlier in this layout,android

原文地址http://www.thinksaas.cn/topics/0/448/448554.html  其實這個訊息也是可以解掉的,當然最簡單的解法就是你不...

2637
来自专栏计算机视觉与深度学习基础

Leetcode 289. Game of Life

According to the Wikipedia's article: "The Game of Life, also known simply as ...

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

HUST 1555 A Math Homework

1555 - A Math Homework 时间限制:1秒 内存限制:128兆 338 次提交 131 次通过 题目描述 QKL is a poor a...

3278
来自专栏醉程序

DES算法中子密钥的产生

973
来自专栏深度学习那些事儿

macOS使用django安装mysqlclient遇到的问题(mysqlclient 1.3.3 or newer is required)

最近需要使用django搭建一个网站,使用的数据库是mysql。 mac电脑里面已经安装好了mysql-5.7-community。 之前使用的python...

1574

扫描关注云+社区