linux 环境下redis 主从复制之 全量复制和部分复制(三)

4 篇文章 0 订阅

1.全量复制和部分复制 相关概念

全量复制:用于初次复制或其它无法进行部分复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作,当数据量较大时,会对主从节点和网络造成很大的开销

部分复制:用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销,需要注意的是,如果网络中断时间过长,造成主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制

2.复制偏移量

参数说明
master_repl_offset参与复制的主从节点都会维护自身复制偏移量。主节点(master)在处理完写入命令后,会把命令的字节长度做累加记录,统计信息在info replication中的master_repl_offset指标中
slave0从节点(slave) 每秒钟上报自身的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量
slave_repl_offset从节点在接收到主节点发送的命令后,也会累加记录自身的偏移量。

【slave节点操作】

127.0.0.1:6379> info replication

在这里插入图片描述
从节点(slave)每秒钟上报自身的复制偏移量给主节点,因此主节点也会保存从节点的复制偏移量,统计指标如下:

【master节点操作】

127.0.0.1:6379> info replication

在这里插入图片描述
从节点(slave)在接收到主节点发送的命令后,也会累加记录自身的偏移量。统计信息在 info relication 中的 slave_repl_offset

【slave节点操作】

127.0.0.1:6379> info replication

在这里插入图片描述

3.复制积压缓冲区

参数说明
repl_backlog_active:1开启复制缓冲区
repl_backlog_size:1048576缓冲区最大长度
repl_backlog_first_byte_offset:1起始偏移量,计算当前缓冲区可用范围
repl_backlog_histlen:2301已保存数据的有效长度
master_replid主节点实例的master_replid相同
master_replid2未发生切换,即主实例未发生过变化,所以初始值为0

3.1.复制积压缓冲区是保存在主节点上的一个固定长度的队列。,默认大小为1MB,当主节点有连接的从节点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区。
在这里插入图片描述

3.2 在命令传播阶段,主节点除了将写命令发送给从节点,还会发送一份给复制积压缓冲区,作为写命令的备份;除了存储写命令,复制积压缓冲区中还存储了其中的每个字节对应的复制偏移量(offset) 。由于复制积压缓冲区定长且先进先出,所以它保存的是主节点最近执行的写命令;时间较早的写命令会被挤出缓冲区。

在这里插入图片描述
4.Redis全量复制的过程如下

在这里插入图片描述
如上图所示:

  1. (从节点slave)Redis 内部会发出一个同步命令,刚开始是 Psync 命令,Psync ? -1表示要求 master 主机同步数据
  2. 主机会向从机发送 runid 和 offset,因为 slave 并没有对应的 offset,所以是全量复制
  3. 从机 slave 会保存 主机master 的基本信息 save masterInfo
  4. 主节点收到全量复制的命令后,执行bgsave(异步执行),在后台生成RDB文件(快照),并使用一个缓冲区(称为复制缓冲区)记录从现在开始执行的所有写命令
  5. 主机send RDB 发送 RDB 文件给从机
  6. 发送缓冲区数据
  7. 刷新旧的数据,从节点在载入主节点的数据之前要先将老数据清除
  8. 加载 RDB 文件将数据库状态更新至主节点执行bgsave时的数据库状态和缓冲区数据的加载

【master 日志截图】:
在这里插入图片描述
【slave 日志截图】
在这里插入图片描述
全量复制开销,主要有以下几项:

  1. bgsave 时间
  2. RDB 文件网络传输时间
  3. 从节点清空数据的时间
  4. 从节点加载 RDB 的时间

5.部分复制

部分复制是 Redis 2.8 以后出现的,之所以要加入部分复制,是因为全量复制会产生很多问题,比如像上面的时间开销大、无法隔离等问题, Redis 希望能够在 master 出现抖动(相当于断开连接)的时候,可以有一些机制将复制的损失降低到最低
在这里插入图片描述

如上图所示:

  1. 如果网络抖动(连接断开 connection lost)
  2. 主机master 还是会写 replbackbuffer(复制缓冲区)
  3. 从机slave 会继续尝试连接主机
  4. 从机slave 会把自己当前 runid 和偏移量传输给主机 master,并且执行 pysnc 命令同步
  5. 如果 master 发现你的偏移量是在缓冲区的范围内,就会返回 continue 命令
  6. 同步了 offset 的部分数据,所以部分复制的基础就是偏移量 offset。

6.正常情况下redis是如何决定是全量复制还是部分复制

从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定能否执行部分复制
1.如果offset偏移量之后的数据,仍然都在复制积压缓冲区里,则执行部分复制
2.如果offset偏移量之后的数据不在复制积压缓冲区中(数据已被挤出),则执行全量复制

7.缓冲区大小调节:

由于缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制。反过来说,为了提高网络中断时部分复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size)来设置。

例如如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用部分复制。

8.服务器运行ID(runid)

每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都不一样),由40个随机的十六进制字符组成;runid用来唯一识别一个Redis节点。 通过info server命令,可以查看节点的runid:
在这里插入图片描述
主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断能否进行部分复制:

如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况)

如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值