Redis中的集群(八)

集群

设置从节点

在这里插入图片描述

向一个节点发送命令:

CLUSTER REPLICATE <node_id>

可以让接收命令的节点成为node_id所指定节点的从节点,并开始对主节点进行复制:

  • 1.接收到该命令的节点会首先会在自己的clusterState.nodes字典中找到node_id所对应节点的clusterNode结构,并将自己的clusterState.myself.slaveof指针指向这个结构,以此来记录这个节点正在复制的主节点:
struct clusterNode {
// ...// 如果这时一个从节点,那么指向主节点
struct clusterNode *slaveof;// ...
}'
  • 2.然后节点会修改自己在clusterState.myself.flags中的属性,关闭原本的REDIS_NODE_MASTER标识,打开REDIS_NODE_SLAVE
    标识,标识这个节点已经由原来的主节点变成了从节点
  • 3.最后节点会调用复制代码,并根据clusterState.myself.slaveof指向的clusterNode结构所保存的IP地址和端口号,对主节点进行复制。
    因为节点的复制功能和单机Redis服务器的复制功能使用了相同的代码,所以让从节点复制主节点相当于向从节点发送命令
SLAVEOF <master_ip> <master_port>

如图所示节点7004在复制节点7000时的clusterState结构:

  • 1.clusterState.myself.flags属性的值为REDIS_NODE_SLAVE,表示节点7004是一个从节点。
  • 2.clusterState.myself.slaveof指针指向代表节点7000的结构,表示节点7004正在复制的主节点为7000节点

一个节点成为从节点,并开始复制某个主节点这一信息会通过消息发送给集群中的其他节点,最终集群中的所有节点都会知道某个从节点
正在复制某个主节点。集群中的所有节点都会在代表主节点的clusterNode结构的slaves属性和numslaves属性中记录正在复制这个主节点的从节点名单:

struct clusterNode {
// ...
// 正在复制这个主节点的从节点数量
int numslaves;// 一个数组
// 每个数组项指向一个正在复制这个主节点的从节点的clusterNode结构
struct clusterNode **slaves;// ...
}

例子

  • 举个例子。图中记录了节点7004和节点7005成为节点7000的从节点之后,集群中的各个节点为节点7000创建的clusterNode结构的样子:
    1.代表节点7000的clusterNode结构的numslaves属性的值为2,这说明有两个从节点正在复制节点7000
    2.代表节点7000的clusterNode结构的slaves数组的两个项分别指向代表节点7004和代表节点7005的clusterNode结构
    这说明节点7000的两个从节点分别是节点7004和节点7005
    在这里插入图片描述

故障检测

集群中的每个节点都会定期地向集群中的其他节点发送PING消息,以此来检测对方是否在线,如果接收PING消息的节点没有在规定的时间内,向发送PING消息的节点返回PONG消息,那么发送PING消息的节点就会将接收PING消息的节点标记为疑似下线(probale fail, PFAIL)

集群中的各个节点会通过互相发送消息的方式来交换集群中各个节点的状态信息,例如某个节点是处于在线状态、疑似下线状态(PFAIL)还是
已下线状态(FAIL).当一个主节点A通过消息得知主节点B认为主节点C进入了疑似下线状态时,主节点A会在自己的clusterState.nodes字典中
找到主节点C所对应的clusterNode结构,并将主节点B的下线报告(failure report)添加到clusterNode结构的fail_reports链表里面:

struct clusterNode {
//...// 一个链表,记录了所有其他节点对该节点的下线报告
list *fail_reports;// ...
}

每个下线报告由一个clusterNodeFailReport结构表示:

struct clusterNodeFailReport {
// 报告目标节点已经下线的节点
struct clusterNode *node;// 最后以此从node节点收到下线报告的时间
// 程序使用这个时间戳来检查下线报告是否过期
// (与当前时间相差太久的下线报告会被删除)
mstime_t time;
}typedef clusterNodeFailReport;

如果在一个集群里面,半数以上负责处理槽的主节点都将某个主节点x报告为疑似下线,那么这个主节点x将被标记为已下线(FAIL),将主节点x标记为已下线会向集群广播一条关于主节点x的FAIL消息,所有收到这条FAIL消息的节点都会立即将主节点x标记为已下线。

例子

  • 举个例子。如果节点7001向节点7000发送了一条PING消息,但是节点7000没有在规定的时间内,向节点7001返回一条PONG消息,
    那么节点7001就会在自己的clusterState.nodes字典中找到7000所对应的clusterNode结构,并在结构的flags属性中打开REDIS_NODE_PFAIL标识,以此表示节点7000进入了疑似下线状态,如图所示在这里插入图片描述
  • 举个例子。如果主节点7001在收到主节点7002、主节点7003发送的消息后得知,主节点7002和主节点7003都认为主节点7000进入了
    疑似下线状态,那么主节点7001将为主节点7000创建如图所示的下线报告.在这里插入图片描述
  • 举个例子,对于上图所示的下线报告来说,主节点7002和主节点7003都认为主节点7000进入了下线状态,并且主节点70001也认为主节点7000
    进入了疑似下线状态(代表主节点7000的结构打开了REDIS_NODE_PFAIL标识),综合起来在集群四个负责处理槽的主节点里面,有三个主节点都
    将主节点标记为下线,数量已经超过了半数,所以主节点7001会将主节点7000标记为已下线,并向集群广播一条关于主节点7000的FAIL消息,
    如图所示在这里插入图片描述

故障转移

当一个从节点发现自己正在复制的主节点进入了已下线状态时,从节点将开始对下线主节点进行故障转移,以下是故障转移的执行步骤:

  • 1.复制下线主节点的所有从节点里面,会有一个从节点被选中
  • 2.被选中的从节点会执行SLAVEOF no one命令,成为新的主节点
  • 3.新的主节点会撤销所有对已下线主节点的槽指派,并将这些槽全部指派给自己
  • 4.新的主节点会向集群广播一条PONG消息,这条PONG消息可以让集群中的其他节点立即知道这个节点已经由从节点变成了主节点,并且
    这个主节点已经接管了原本由已下线节点负责处理的槽
  • 5.新的主节点开始接收和自己负责处理的槽的有关的命令请求,故障转移完成

选举新的主节点

新的主节点是通过选举产生的。以下是集群选举新的主节点的方法:

  • 1.集群的配置纪元是一个自增计数器,它的初始值为0
  • 2.当集群里的某个节点开始一次故障转移操作时,集群配置纪元的值就会被增一
  • 3.对于每个配置纪元,集群里每个负责处理槽的主节点都有一次投票的机会,而的哥向主节点要求投票的从节点将获得主节点的投票
  • 4.当从节点发现自己正在复制的主节点进入已下线状态时,从节点会向集群广播一条CLUSTERMSG_TYPE_FAILOVER_AUTH_REQUEST
    消息,要求所有收到这条消息,并且具有投票权的主节点向这个从节点投票
  • 5.如果一个主节点具有投票权(它正在负责处理槽),并且这个主节点尚未投票给其他从节点,那么主节点将向要求投票的从节点返回一条
    CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,表示这个主节点支持从节点成为新的主节点
  • 6.每个参与选举的从节点都会接收CLUSTERMSG_TYPE_FAILOVER_AUTH_ACK消息,并根据自己收到了多少条这种消息来统计自己获得了多少主节点的支持
  • 7.如果集群里有N个具有投票权的主节点,那么当一个从节点的收集到大于等于N/2+1张支持票时,这个从节点就会当选为新的主节点
  • 8.因为在每一个配置纪元里面,每个具有投票权的主节点只能投一次票,所以如果有N个主节点进行投票,那么具有大于等于N/2+1张支持
    票的从节点只会有一个,这确保了主节点只会有一个
  • 9.如果在一个配置纪元里面没有从节点能收集到足够多的支持票,那么集群进入一个新的配置纪元,并再次进行选举,知道选出新的主节点为止

这个选举主节点的方法和选举领头Sentinel的方法非常相似,因为两者都是基于Raft算法的领头选举(leader election)方法来实现的

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/615583.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Web3 的社会影响:数字社会的新时代

随着科技的不断进步和创新&#xff0c;人类社会正逐步进入数字化时代的新阶段。Web3 技术作为数字社会的重要组成部分&#xff0c;正在以前所未有的方式重塑着我们的社会生活和交往方式。本文将探讨 Web3 技术对社会的影响&#xff0c;以及它所带来的数字社会的新时代。 1. Web…

ClickHouse--16--普通函数

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 一、日期函数1、时间或日期截取函数&#xff08;返回非日期&#xff09;2、时间或日期截取函数&#xff08;返回日期&#xff09;3、日期或时间日期生成函数 二、类…

SD-WAN企业网络部署模式及适用企业类型

随着企业规模的扩张和数字化转型的推进&#xff0c;SD-WAN作为一种灵活、安全和高效的组网解决方案备受关注。那么&#xff0c;SD-WAN在企业网络部署中有哪些常见模式&#xff1f;又有哪些类型的企业最适合采用SD-WAN呢&#xff1f;让我们一起来了解一下&#xff01; 常见的SD-…

【海思Hi3516CV610】是面向新一代视频编解码标准、网络安全和隐私保护、人工智能行业应用方面的IPC SoC

海思Hi3516CV610是面向新一代视频编解码标准、网络安全和隐私保护、人工智能行业应用方面的IPC SoC&#xff0c;除了开发普通摄像机&#xff0c;还可以打造极具竞争力的枪球一体机、双目长短焦摄像机产品&#xff1b; 处理器内核: 支持ARM Cortex-A7 MP2 时钟速率950MHz 支持…

项目5-博客系统4+加密/加盐

1.加密介绍 在MySQL数据库中, 我们常常需要对密码, ⾝份证号, ⼿机号等敏感信息进⾏加密, 以保证数据的安全性. 如果使⽤明⽂存储, 当⿊客⼊侵了数据库时, 就可以轻松获取到⽤⼾的相关信息, 从⽽对⽤⼾或者企业造成信息泄漏或者财产损失. ⽬前我们⽤⼾的密码还是明⽂设置的, …

表格头部合并,数据和表头中间插入合计和样式合并

在做项目时其中一个页面要求和Excel格式一样的页面 html数据&#xff0c;大概写了几个案例如下 <el-table v-loading"loading" :data"tableList" :span-method"mergeRow">//:span-method"mergeRow" 用于合并第一行<el-table…

常用的几款性能测试软件

Apache JMeter是一款免费、开源的性能测试工具&#xff0c;广泛应用于Web应用程序和服务的性能测试。它支持模拟多种不同类型的负载&#xff0c;可以测试应用程序在不同压力下的性能表现&#xff0c;并提供丰富的图表和报告来分析测试结果。 优点&#xff1a; 免费且开源&…

ActiveMQ介绍及linux下安装ActiveMQ

ActiveMQ介绍 概述 ActiveMQ是Apache软件基金下的一个开源软件&#xff0c;它遵循JMS1.1规范&#xff08;Java Message Service&#xff09;&#xff0c;是消息队列服务&#xff0c;是面向消息中间件&#xff08;MOM&#xff09;的最终实现&#xff0c;它为企业消息传递提供高…

基于SSM+Jsp+Mysql的社区生活超市管理系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

IPv4头部

IPv4头部 互联网协议&#xff08;IP&#xff09;的核心部分&#xff0c;用于在互联网上传输数据包。IPv4头部包含多个字段&#xff0c;这些字段对于正确地路由和传递数据至目的地至关重要。IPv4头部通常是20字节长&#xff0c;但可以因选项字段的存在而更长。以下是IPv4头部各个…

Ubuntu20.04版本命令行设置挂载磁盘,并设置开机自动挂载

最近部署应用 系统是Ubuntu20.4版本的Linux系统&#xff0c;加了数据盘&#xff0c;需要格式化后挂载&#xff0c;记录下&#xff1a; Linux 数据盘挂载(采用 parted 分区工具)-格式化为 ext4 1. 初始化 Linux 数据盘 挂载数据盘后或者随实例创建时一并创建的数据盘&#xff…

HarmonyOS4 页面路由

Index.ets: import router from ohos.routerclass RouterInfo {// 页面路径url: string// 页面标题title: stringconstructor(url: string, title: string) {this.url urlthis.title title} }Entry // 入口組件 Component struct Index {State message: string 页面列表// …