redis数据同步时的过程

本文详细介绍了Redis 2.8及以上版本的主从复制,区分了全量复制和增量复制的工作原理,以及它们在数据同步中的应用场景。特别关注了RDB文件、复制偏移量、复制积压缓冲区和网络恢复时的同步策略。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

叙述

今天我们来探讨一下redis的主从复制的数据同步阶段的全量复制和增量复制.

数据同步过程

在Redis2.8以前,从节点向主节点发送sync命令请求同步数据,此时的同步方式是全量复制;在Redis2.8及以后,从节点可以发送psync命令请求同步数据,此时根据主从节点当前状态的不同,同步方式可能是全量复制或增量复制。
下面介绍以Redis2.8及以后版本为例。

  • 全量复制:用于初次复制或其它无法进行增量复制的情况,将主节点中的所有数据都发送给从节点,是一个非常重型的操作。
  • 增量复制:用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效。需要注意的是,如果网络中断时间过长,造成主节点没有能够完整地保存中断期间执行的写命令,则无法进行增量复制,仍使用全量复制。

redis2.8 版本之前

在这里插入图片描述

复制过程说明:

  • slave 服务启动,slave 会建立和 master 的连接,发送 sync 命令。
  • master 启动一个后台进程将数据库快照保存到 RDB 文件中

 注意:此时如果生成 RDB 文件过程中存在写数据操作会导致 RDB 文件和当前主 redis 数据不一致,所以此时 master
主进程会开始收集写命令并缓存起来。

  • master 就发送 RDB 文件给 slave
  • slave 将文件保存到磁盘上,然后加载到内存恢复
  • master 把缓存的命令转发给 slave

注意:后续 master 收到的写命令都会通过开始建立的连接发送给 slave。
当 master 和 slave 的连接断开时 slave 可以自动重新建立连接。如果 master 同时收到多个 slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有 slave。
 

完整复制的问题:

在 redis2.8 之前从 redis 每次同步都会从主 redis 中复制全部的数据,如果从 redis 是新创建的从主 redis 中复制全部的数据这是没有问题的,但是,如果当从 redis 停止运行,再启动时可能只有少增量数据和主 redis 不同步,此时启动 redis 仍然会从主 redis 复制全部数据,这样的性能肯定没有只复制那一小增量不同步的数据高。

redis2.8 版本之后

1、全量复制

Redis通过psync命令进行全量复制的过程如下:

  • 从节点判断无法进行增量复制,向主节点发送全量复制的请求;或从节点发送增量复制的请求,但主节点判断无法进行全量复制。
  • 主节点收到全量复制的命令后,执行bgsave,在后台生成RDB文件,并使用一个缓冲区(称为复制缓冲区)记录从现在开始执行的所有写命令。
  • 主节点的bgsave执行完成后,将RDB文件发送给从节点;从节点首先清除自己的旧数据,然后载入接收的RDB文件,将数据库状态更新至主节点执行bgsave时的数据库状态。
  • 主节点将前述复制缓冲区中的所有写命令发送给从节点,从节点执行这些写命令,将数据库状态更新至主节点的最新状态。
  • 如果从节点开启了AOF,则会触发bgrewriteaof的执行,从而保证AOF文件更新至主节点的最新状态。

2、增量复制

由于全量复制在主节点数据量较大时效率太低,因此Redis2.8开始提供增量复制,用于处理网络中断时的数据同步。
增量复制的实现,依赖于三个重要的概念:

复制偏移量

主节点和从节点分别维护一个复制偏移量(offset),代表的是主节点向从节点传递的字节数;主节点每次向从节点传播N个字节数据时,主节点的offset增加N;从节点每次收到主节点传来的N个字节数据时,从节点的offset增加N。

offset用于判断主从节点的数据库状态是否一致:如果二者offset相同,则一致;如果offset不同,则不一致,此时可以根据两个offset找出从节点缺少的那增量数据。例如,如果主节点的offset是1000,而从节点的offset是500,那么增量复制就需要将offset为501-1000的数据传递给从节点,而offset为501-1000的数据存储的位置,就是下面要介绍的复制积压缓冲区。
 

复制积压缓冲区

复制积压缓冲区是由主节点维护的、固定长度的、先进先出(FIFO)队列,默认大小1MB;当主节点开始有从节点时创建,其作用是备份主节点最近发送给从节点的数据。注意,无论主节点有一个还是多个从节点,都只需要一个复制积压缓冲区

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

由于该缓冲区长度固定且有限,因此可以备份的写命令也有限,当主从节点offset的差距过大超过缓冲区长度时,将无法执行增量复制,只能执行全量复制。反过来说,为了提高网络中断时增量复制执行的概率,可以根据需要增大复制积压缓冲区的大小(通过配置repl-backlog-size)来设置;例如如果网络中断的平均时间是60s,而主节点平均每秒产生的写命令(特定协议格式)所占的字节数为100KB,则复制积压缓冲区的平均需求为6MB,保险起见,可以设置为12MB,来保证绝大多数断线情况都可以使用增量复制。

从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定能否执行增量复制:

  • 如果offset偏移量之后的数据,仍然都在复制积压缓冲区里,则执行增量复制;
  • 如果offset偏移量之后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制。
     

repl_backlog_buffer 缓行缓冲区(复制积压缓冲区)的默认大小是 1M,并且由于它是一个环形缓冲区,所以当缓冲区写满后,主服务器继续写入的话,就会覆盖之前的数据。因此,当主服务器的写入速度远超于从服务器的读取速度,缓冲区的数据一下就会被覆盖。

那么在网络恢复时,如果从服务器想读的数据已经被覆盖了,主服务器就会采用全量同步,这个方式比增量同步的性能损耗要大很多。

主从复制中两个 Buffer(replication buffer 、repl backlog buffer)有什么区别?

replication buffer 、repl backlog buffer 区别如下:

  • 出现的阶段不一样:
    • repl backlog buffer 是在增量复制阶段出现,一个主节点只分配一个 repl backlog buffer
    • replication buffer 是在全量复制阶段和增量复制阶段都会出现,主节点会给每个新连接的从节点,分配一个 replication buffer
  • 这两个 Buffer 都有大小限制的,当缓冲区满了之后,发生的事情不一样:
    • 当 repl backlog buffer 满了,因为是环形结构,会直接覆盖起始位置数据;
    • 当 replication buffer 满了,会导致连接断开,删除缓存,从节点重新连接,重新开始全量复制

 

服务器运行ID(runid)

每个Redis节点(无论主从),在启动时都会自动生成一个随机ID(每次启动都不一样),由40个随机的十六进制字符组成;runid用来唯一识别一个Redis节点。 通过info server命令,可以查看节点的runid:

主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来;当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断能否进行增量复制:

如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用增量复制(到底能不能增量复制还要看offset和复制积压缓冲区的情况);
如果从节点保存的runid与主节点现在的runid不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制.
在这里插入图片描述

增量复制说明:

从机连接主机后,会主动发起 PSYNC 命令,从机会提供 master 的 runid(机器标识,随机生成的一个串) 和 offset(数据偏移量,如果offset主从不一致则说明数据不同步),主机验证 runid 和 offset 是否有效,runid 相当于主机身份验证码,用来验证从机上一次连接的主机,如果 runid 验证未通过则,则进行全同步,如果验证通过则说明曾经同步过,根据 offset 同步部分数据。

小结

关于主从复制的数据同步时候的全量复制,你有点了解了吗?


————————————————
版权声明:本文为优快云博主「Hi-Sunshine」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.youkuaiyun.com/zmh458/article/details/89600299 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值