主从库与切片集群机制

news/2024/9/19 20:01:48/文章来源:https://www.cnblogs.com/pinoky/p/18414850

主从库与切片集群机制

主从复制源码剖析

redis的主从复制主要包括全量复制RDB文件,增量复制,长连接同步,使用了基于状态机的设计思想,来实现不同状态和状态间的跳转

基于状态机实现的话,在开发程序时只需要考虑不同状态下具体要执行的操作,以及状态之间的跳转条件即可

四大阶段

img

初始化阶段:将实例A设置为B的从库,获取主库的ip和port

建立连接阶段:实例A尝试与主库建立TCP连接,并在连接上监听主库的命令

主从握手阶段:主从库间相互发送 PING-PONG 消息,同时从库根据配置信息向主库进行验证

复制类型判断和执行阶段:主库会根据从库发送的命令参数作出相应的三种回复,分别是执行全量复制、执行增量复制、发生错误。最后,从库在收到上述回复后,就会根据回复的复制类型,开始执行具体的复制操作

状态机实现

在每个redis实例里都对应着一个redisServer结构体,在其中与主从复制状态机相关的变量是repl_state

初始化阶段

实例启动后,把状态机初始状态设置为REPL_STATE_NONE,而一旦执行了replicaof masterip masterport之后,会设置主库IP和端口号,并把状态机设置为REPL_STATE_CONNECT,完成初始化阶段

建立连接阶段

redis会每隔1000ms调用replicationCron()执行任务,检查复制状态机状态为REPL_STATE_CONNECT的话就开始和主库建立连接,然后在连接上创建读写事件并且注册处理读写事件的函数syncWithMater,然后将从库状态机设置为REPL_STATE_CONNECTING

主从握手阶段

一旦主从库间连接建立,从库实例中的syncWithMaster函数被回调,在该函数中如果从库实例状态为REPL_STATE_CONNECTING,就会发送PING消息给主库,并设置状态机为REPL_STATE_RECEIVE_PONG

然后从库会依次发送验证信息、端口号、IP、对RDB文件和无盘复制的支持情况,每一次握手发送信息时都对应着从库的一组状态变迁(发送前是SEND状态,发送完成后是RECEIVE状态并开始读取主库返回的结果)

复制类型判断与执行阶段

完成握手之后,从库状态变迁为REPL_STATE_SEND_PSYNC,表明开始向主库发送PSYNC命令,开始实际的数据同步,当调用函数完成发送之后又变迁为REPL_STATE_RECEIVE_PSYNC,这个调用函数会负责向主库发送数据同步的命令,并根据主库的回复消息将返回值置为不同结果

然后syncWithMaster根据返回值的不同执行不同处理,比如返回FULLRESYNC,从库会在和主库的网络连接上注册readSyncBulkPayload函数,并将状态机设置为REPL_STATE_TRANSFER,表明开始实际的数据同步

img

哨兵和raft

redis哨兵leader选举实现时涉及到raft协议,区别在于:在正常运行时,不同实例间不是leader和follower的关系,而是对等的关系

实现哨兵实例工作主题逻辑的函数:sentinelHandleRedisInstance函数,周期性执行检测哨兵监听节点的状态

  • 重建连接:尝试和断连的实例重建连接
  • 发送命令:向实例发送ping、info等命令
  • 判断主观下线:检查监听的实例是否主观下线
  • 判断客观下线和执行故障切换:首先真对监听的主节点判断是否客观下线;接着判断是否要启动故障切换,如果需要就再获取其他哨兵对主节点状态的判断,并向其他哨兵发送is-master-down-by-addr命令发起leader选举,随后执行故障切换,最后再获取对新主节点的状态判断

img

判断主节点是否客观下线的函数逻辑:通过遍历监听同一主节点的其他哨兵的 flags 变量,来判断主节点是否客观下线的。

imgimg

随后判断是否要进行故障切换的条件有三个:

  • 主节点的 flags 已经标记了 SRI_O_DOWN;
  • 当前没有在执行故障切换;
  • 如果已经开始故障切换,那么开始时间距离当前时间,需要超过 sentinel.conf 文件中的 sentinel failover-timeout 配置项的 2 倍。

同时sentinelAskMasterStateToOtherSentinels用于给其他哨兵发送 sentinel is-master-down-by-addr,命令包括主节点ip,主节点port,当前纪元和实例ID,如果实例ID不是*,则会调用sentinelVoteLeader进行哨兵的Leader选举

假设哨兵A判断主节点master客观下线,它向B发起投票请求,B执行sentinelVoteLeader时会判断A、B、master记录的leader纪元,通过纪元来进行轮次记录从而让follower在一轮中只能投一票,只有master的leader纪元小于哨兵A纪元,且B纪元小于等于A纪元,保证B还没有投过票,才能给A投票

最终leader当选的条件是:获得超过半数的,且超过预设的quorum阈值的其他哨兵赞成票

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

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

相关文章

数据类型与底层原理

数据类型与底层原理 数据结构 哈希表 redis使用链式哈希来解决哈希冲突,其Hash表实质上是一个二维数组,其中每一项就是一个指向哈希项(dictEntry)的指针 typedef struct dictht {dictEntry **table; //二维数组unsigned long size; //Hash表大小unsigned long sizemask;uns…

软工作业2:个人项目-论文查重

一、github链接这个作业属于哪个课程 首页 - 计科22级12班 - 广东工业大学 - 班级博客 - 博客园 (cnblogs.com)这个作业要求在哪里 个人项目 - 作业 - 计科22级12班 - 班级博客 - 博客园 (cnblogs.com)这个作业的目标 规范代码编写;学习模块化管理程序功能;学会写单元测试二、…

软工第一次编程作业:论文查重

github地址:https://github.com/yingnothing/first.git 个人项目-论文查重这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229GitHub链接 https://github.com/ying…

个人项目——论文查重

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229这个作业的目标 个人项目——论文查重一:我的github仓库地址 https://github.com/kelin-KL/kelin-KL 二:PSP表格…

OI海海

在pyq里看到了殿禾Wrose的“X的随波逐流”,附文是“我与OI的365天”,我才想到,我打OI也整整一年了 有人或许不理解我这样的一个蒟蒻为什么这么喜欢喜欢写怀念类的东西,即使到现在我还没有取得任何的奖项以及未来也并没有概率拿牌 因为我只觉得一步步走来,不记得的话,是很…

GIS可视化软件:地理信息与遥感领域中的洞察之眼

在地理信息与遥感技术的广阔天地中,可视化软件如同一双洞察世界的明眸,将复杂的数据编织成生动、直观的画卷,为我们揭示地球的奥秘与城市的律动。本文将深入挖掘其技术核心、应用实例、未来趋势,探讨可视化软件如何为地理信息与遥感技术带来深刻洞见。 可视化软件的核心与技…

USB分析仪USB3.2日志分析

1.简介 USB2.0总线采用轮询模式,即总线事务开始时,都要先发送IN或者OUT令牌包,以通知端点或者查询端点是否准备好。而USB3.2采用了异步通知模式,若端点没有准备好,则主机无需轮询,端点准备好后会通知主机,而对于OUT端点,主机会直接发送DP数据包,相当于将USB2.0中的OUT…

[第一章 web入门]SQL注入-1

启动靶机很明显注入点为id值,单引号闭合影响语句,说明为单引号闭合构造注入语句 ?id=1 and 1 =1 --+ 发现没报错,说明没有其他过滤 ,开始sql注入 ?id=1 order by 4 --+ 直到=4报错说明有3个字节段测试回显位2,3 ?id=1 and 1 = 2 union select 1,2,3 --+ 测试当…

数据结构 —堆

今天学习算法了没,你小子瞅啥呢!一:堆 1、一种二叉树的结构(完全二叉树) 2、完全二叉树:从上到下;从左到右;填满 3、最大堆:根节点的权值大于孩子节点 4、最小堆:根节点的权值依次小于孩子节点 5、常用操作 import heapq# 创建最小堆和最大堆 min_heap = [] max_heap…

软工第一次作业-论文查重

这个作业属于哪个课程 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/这个作业要求在哪里 https://edu.cnblogs.com/campus/gdgy/CSGrade22-34/homework/13229这个作业的目标 通过Java开发个人项目,实现项目单元测试作业github地址(含jar包) github:https://github.com/…

第二十讲:为什么我只改一行的语句,锁这么多?

该文章深刻揭示了一点:加索引=行锁+间隙锁=(next-key lock),分析了加锁的规则:对主键(唯一索引),普通非唯一索引进行等值与范围查询的加锁。这篇文章我认为收获最大的是让我们知道“明明对一行加了锁,为什么在他相邻部分,或是相相邻部分无法插入数据(这根主键类型,…