redis的主从复制原理

引子

在分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,复制功能是
高可用redis的基础,redis哨兵机制以及集群都是在复制的基础上实现高可用。

复制两种使用方式

// 在从节点客户端执行如下命令,让其成为某个主节点的从节点:
slaveof ip port
// 断开复制
slaveof no one

配置文件配置:
在这里插入图片描述

主从复制原理

保存主节点信息:

通过执行slaveof ip port命令后,从节点只是保存了主节点的地址信息。

主从建立socket连接

从节点通过没秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接,从节点会建立一个socket套接字,专门用于接收主节点发送的复制命令。
在这里插入图片描述通过在从节点执行 info replication观察 master_link_status:up,知道从节点与主节点已经建立连接。

发送ping命令:

连接建立后从节点发送ping请求进行首次通信,ping主要目的:检测主从之间网络套接字是否可用
检测主节点当前是否可接受处理命令。发送ping命令后,从节点没有收到主节点的pong或者超时,
从节点会断开复制链接,下次定时任务会重新发起重连。

权限验证

主节点设置了requirepass参数,则需要密码验证,从节点必须配置masterauth参数保证与主节点
相同的密码才可以保证通过验证,验证失败将终止复制,从节点重新发起复制流程。

同步数据

主从复制连接正常通信后,首次建立复制的场景,采用全量复制,redis 2.8版本后采用复制命令psync进行数据同步,同时2.8版本后同步划分为全量同步和部分同步。

命令持续复制

当主节点把当前的数据同步给从节点后,便完成了复制的建立流程,接下来主节点会持续地把写
命令同步给从节点。

全量复制与增量复制:

首先介绍复制偏移量:参与复制的主从节点都会维护自身的复制偏移量,主节点在处理完写命令后,会把命令的字节长度进行累加。 统计信息可以根据info replication查看。
从节点每秒钟上报自身的偏移量给主节点,所以主节点通过info replication命令,也可以查看到slave的offset偏移量。
在这里插入图片描述

从节点偏移量:
在这里插入图片描述在这里插入图片描述这里之所以不一致是因为主从偏移量每秒都会做同步。
同时这里还有介绍一下run_id:
runid作用:Runid:redis节点每次启动后都会随机生成一个id,来保证标识。Redis从节点首次连到主节点会获取runid,然后保存,下次复制时,检查主节点runid是否变化,如果变化,那么就会进行全量复制。
扩展:如何在不改变runid的情况下进行重启:
比如进行调优内存相关配置时,例如:hash-max-ziplist-value,需要redis重新加载才能优化已经
存在的数据
这时可以使用 ==debug reload ===命令,debug reload命令会阻塞当前redis节点主线程,阻塞期间会生成本地rdb快照,然后清空数据,再重新加载RDB文件,这时就需要考虑对于大数据量的主节点同时有并发写请求时,如果无法容忍阻塞,就要谨慎使用。

全量同步过程:

slave向主节点发送同步请求,slave会告知master自己的偏移量offset,第一次offset=-1
slave连上了master,master会给slave分配一个client buffer(这个就是复制缓冲区replication buffer)
master fork子进程dump RDB文件,dump完成后告诉父进程,父进程把RDB发给slave(通过slave的socket发过去)
在master dump RDB期间,master所有写命令,都写到这个client buffer(replication buffer),先积压在这
RDB发送完成,master把client buffer(replication buffer)积压的命令,都发给slave(写slave socket),这样主从数据就追平了
之后master写请求,还是都写到client buffer(replication buffer),然后实时传播给slave,主从保持一致
此时还要引入backlog_buffer概念
1、只要master下面有slave存在,master就会分配一块内存,这块内存就是backlog buffer
2、只要master有写命令进来,也都会写一份到backlog buffer里,但这个buffer是固定大小的环形缓冲区,写满就会覆盖旧数据
3、它的作用在于,主从复制意外中断了,slave再次向master发起同步请求,slave会告知master要从哪开始复制(offset),master在backlog buffer里找,数据能否接得上,接得上就把差异的增量数据发给slave,发的过程也是先写到上面所说的client buffer(replication buffer),然后写slave socket达到主从同步
4、如果接不上,走全量同步
从节点接收到主节点传送过来的全部数据后
从节点先清空数据后然后开始加载RDB文件,从节点加载RDB文件后,如果当前从节点开启AOF持久化后,他会立刻做bgrewriteaof操作。

部分复制:

如果主从节点之间出现网络闪断,或者命令丢失的情况,从节点会向主节点要求补发丢失的命令数据,slave会告知master要从哪开始复制(offset),master在backlog buffer里找,数据能否接得上,接得上就把差异的增量数据发给slave。这时就可以保持主从节点的数据一致性。并且开销很小。

// 无盘复制
repl-diskless-sync 默认关闭
引入无盘复制:为了降低主节点磁磁盘开销,redis支持无盘复制,生成的rdb文件不保存到磁盘,而是直接通过网络发送给从节点,
无盘复制适用于主节点所在机器磁盘性能较差但网络较宽裕的场景。

心跳检测机制

主节点每隔10s对从节点发送1次ping命令,判断从节点的存活性能和连接状态,可通过参数
repl-ping-slave-period控制发送频率。
从节点每隔1s向主节点发送replconf ack offset命令,给主节点汇报自身的偏移量,主节点也会保存
从节点的偏移量。
replconf 作用:

  1. 实时检测主从节点网络状态
  2. 上报自身偏移量,检查复制数据是否丢失,如果从节点数据丢失,再从主节点的复制缓冲区拉取丢失数据
  3. 实现保证从节点的数量和延迟功能。在info replication统计信息中,lag表示与从节点最后一次通信延迟的秒数,正常延迟应该在0和1之间,如果超过repl-timeout配置的值,则判定从节点下线并断开复制客户端连接。
    repl_timeout:
    slave角度,在repl-timeout没有收到master发送的数据包,从节点将放弃接受rdb文件并清理已经下载的临时文件
    master角度,在repl-timeout时间没有收到REPCONF ACK确认信息,则判定从节点下线并断开复制客户端连接
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值