Redis主从复制原理剖析

生产环境中,为保证Redis缓存系统的高可用性,对于Redis集群,一般都会采用主从架构来实现读写分离。
那么主从架构下,主节点和从节点间,数据是如何进行复制和同步,中间是一个什么样的流程,通过本文,想跟众博友和同行一起讨论。
首先看一个图。
Redis主从复制流程图

上图展示了Slave节点第一次连接主节点和短暂断开后再次连接主节点的情况下,数据复制的流程。

  1. 当从节点启动后,会根据自身配置文件中slave of配置的内容,得到主节点的IP和端口。
  2. 从节点向主节点发送一个psync命令(如果主节点设置了秘钥等安全信息,则需带上主节点的安全信息),看看主节点是否能够连接,如果主节点成功连接,则返回主节点的run id、offset信息,同时触发全量复制(Full Resynchronizztion)。
  3. 主节点fork一个子进程,执行bgsave命令,生成一个rdb快照。通过主节点中repl-diskless-sync、repl-diskless-sync-delay两个配置,来选择是否开启无磁盘化的复制。
  • repl-diskless-sync默认为no,即不开启无磁盘化配置,那么在全量复制开始时,主节点fork出的子进程将rdb快照写入磁盘。然后文件通过父进程传输给排队执行全量复制的所有Slave节点。

  • repl-diskless-sync如果设置为yes,即开启无磁盘化复制,无磁盘化复制指的就是主进程fork子进程生成rdb快照文件时,该文件在主节点上不落盘,而是通过与Slave节点建立的socket连接直接将文件推送给Slave节点。

  • repl-diskless-sync如果设置为yes,此时为了让同一份rdb文件能够同时提供给更多的Slave节点,需配合repl-diskless-sync-delay这个配置一起使用。repl-diskless-sync-delay指的是在创建子进程生成rdb快照之前等待一段时间(如5秒),期望更多的子节点与主节点之间建立socket连接,生成rdb文件之后可以一次性复制给多个子节点。

    在子进程生成rdb文件并与从节点间进程rdb文件数据复制的过程中,新写入的数据,Redis将会存储到缓冲区。缓冲区大小可以通过client-output-buffer-limit这个配置来设置。如:

client-output-buffer-limit slave 256MB 64MB 60
指的就是在rdb快照复制过程中,如果缓冲区数据超过256M,
或者持续60秒超过64M,则同步失败。
  1. Redis子进程通过与从节点建立的Socket连接,直接发送rdb快照给Slave节点。
  2. Slave节点收到rdb快照后落盘,然后进行载入。
  3. 从节点完成rdb快照载入之后,Redis发送新写入到缓冲区的数据写命令给从节点,执行增量复制,保证主节点和从节点的数据一致。
  4. 后续每写入一条数据,主节点都会异步将该数据的写命令发送给从节点。
  5. 因为某些原因,从节点与主节点短暂断开连接,导致主从节点数据不一致。
  6. 当slave连接到master,会执行PSYNC <runid> <offset>发送记录旧的master的runid(replication ID)和偏移量offset,这样master能够只发送slave所缺的增量部分。但是如果master的复制积压缓存区没有足够的命令记录,或者slave传的runid(replication ID)不对,就会进行完整重同步,即slave会获得一个完整的数据集副本。
  • 部分数据同步,需要的几个参考值解释如下:

  • run id(replication ID),每个Redis服务启动时,都会生成一个run id,从节点与主节点建立连接后,主节点会将自己的run id同步给从节点。

  • offset:复制偏移量,主节点和从节点各自维护了一个复制偏移量,记录传输的字节数。当主节点向从节点发送N个字节数据时,主节点的offset增加N,从节点收到主节点传来的N个字节数据时,从节点的offset增加N。

  • replication backlog buffer,复制积压缓冲区。是一个固定长度的FIFO队列,大小由配置参数repl-backlog-size指定,默认大小1MB。需要注意的是该缓冲区由master维护并且有且只有一个,所有slave共享此缓冲区,其作用在于备份最近主库发送给从库的数据。

  1. 主节点判断,重新建立连接的从节点,符合部分数据同步的条件,将复制积压缓冲区的数据写命令,发送给从节点,完成数据复制。

小结:

从上述的整个流程我们不难看出,使用Redis主从架构,基于其数据复制的规则和原理,为了数据的安全,我们必须开启主节点的持久化功能,并且在数据量极大的情况下,一定要做好主节点数据备份的策略,避免因为主节点宕机重启而造成大量数据丢失,最后造成不可挽回损失。

因为如果主节点不做数据持久化,主节点宕机重启后,由于run id重启后发生了变化,所有从节点重新与主节点建立连接后,都会全量同步主节点的数据,但是主节点没有持久化数据,从节点也就全部都会被清空。

即使使用Redis哨兵,可以在主节点宕机后将从节点提升为主节点,但是在某些极端情况下,假设你的服务器允许自动重启Redis进程,Redis主节点宕机到重启的这个短暂时间内,Redis哨兵还未来得及发现主节点下线,也会造成数据丢失。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

RonTech

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值