Redis的主从同步原理

一、Redis中数据持久化策略

6.1 RDB

RDB全称Redis Database Backup file(Redis数据备份文件),也被叫做Redis数据快照。简单来说就是把内存中的所有数据都记录到磁盘中(形成一个数据备份文件)。当Redis实例故障重启后,从磁盘读取快照文件,恢复数据。快照文件称为RDB文件,默认是保存在当前运行目录。【RDB是Redis默认持久化的方式

简单理解:就是在触发了这个时机,那么Reids就会对当前内存中的数据生成一份 数据备份文件 以便于后面的数据恢复操作。

执行时机:

  • 执行save(同步阻塞生成数据备份文件)、bgsave命令(异步非阻塞,fork主进程得到子进程)

  • Redis停机时

  • 触发RDB条件时:save 900 1、save 300 10 、save 60 10000(900秒内,如果至少有1个key被修改,则执行bgsave, 如果是save "" 则表示禁用RDB)

fork就是指代主进程的分支,子进程

原理:bgsave开始时会

(1)fork主进程得到子进程,子进程共享主进程的内存数据。

(2)完成fork后读取内存数据并写入 RDB 文件。

(3)用新RDB文件替换旧的RDB文件。

fork采用的是copy-on-write技术:

  • 当主进程执行读操作时,访问共享内存;

  • 当主进程执行写操作时,则会拷贝一份数据,执行写操作。

 

RDB的缺点?

  • RDB执行间隔时间长,两次RDB之间写入数据有丢失的风险

  • fork子进程、压缩、写出RDB文件都比较耗时

6.2 AOF

AOF全称为Append Only File(追加文件)。Redis处理的每一个写命令都会记录在AOF文件,可以看做是命令日志文1件。(将所有的命令,都记录在AOF文件中,相当于日志执行文件,MySQL中的undo slog),AOF默认是关闭的。

AOF的执行策略:

  • appendfsync always:每执行一次写命令,立即记录到AOF文件

  • appendfsync everysec:写命令执行完先放入AOF缓冲区,然后每隔1秒将缓冲区数据写到AOF文件,是默认方案

  • appendfsync no:写命令执行完先放入AOF缓冲区,由操作系统决定何时将缓冲区内容写回磁盘

 

AOF的重写机制:

因为是记录命令,AOF文件会比RDB文件大的多。而且AOF会记录对同一个key的多次写操作,但只有最后一次写操作才有意义。通过执行bgrewriteaof命令,可以让AOF文件执行重写功能,用最少的命令达到相同效果。

假设AOF原本有三个命令,但是set num 123 和 set num 666都是对num的操作,第二次会覆盖第一次的值,因此第一个命令记录下来没有意义。所以重写命令后,AOF文件内容就是:mset name jack num 666

触发重写条件:

  • auto-aof-rewrite-percentage 100:AOF文件比上次文件 增长超过多少百分比则触发重写

  • auto-aof-rewrite-min-size 64mb:AOF文件体积最小多大以上才触发重写

6.3 RDB和AOF对比

RDB和AOF各有自己的优缺点,如果对数据安全性要求较高,在实际开发中往往会结合两者来使用。

二、Redis主从节点数据同步策略

7.1 全量同步

7.1.1 概念

master(主节点)将完整内存数据生成RDB文件,然后将RDB文件发送到slave(从节点)。后续master中执行的命令则记录在 repl_baklog 中,逐个发送给slave。

这里有一个问题,master如何得知salve是第一次连接呢??

有几个概念,可以作为判断依据:

  • Replication Id:简称replid,是数据集的标记,id一致则说明是同一数据集。每一个master都有唯一的replid,slave则会继承master节点的replid。

  • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

因此slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据。

master判断一个节点是否是第一次同步的依据,就是看replid是否一致,不一致的话:那么就需要做全量同步。

7.1.2 完整执行流程描述

  • slave节点请求增量同步(默认都是请求增量同步)。

  • master节点判断replid,发现不一致,拒绝增量同步。

  • master将完整内存数据生成RDB,发送RDB到slave。

  • slave清空本地数据,加载master的RDB。

  • master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave。

  • slave执行接收到的命令,保持与master之间的同步。

7.2 增量同步

7.2.1 概念

全量同步需要先做RDB,然后将RDB文件通过网络传输个slave,成本太高了。因此除了第一次做全量同步,其它大多数时候slave与master都是做增量同步

什么是增量同步?就是只更新slave与master存在差异的部分数据,从offset之后的数据开始同步。如图:

 

7.2.2 repl_backlog原理

  • repl_baklog是全量同步中的日志文件,用于记录主节点master中执行的命令,感觉与AOF一致的感觉。

  • 这个文件是一个固定大小的数组,只不过数组是环形,也就是说角标到达数组末尾后,会再次从0开始读写,这样数组头部的数据就会被覆盖。

  • repl_baklog中会记录Redis处理过的命令日志及offset,包括master当前的offset,和slave已经拷贝到的offset

  • slave与master的offset之间的差异,就是salve需要增量拷贝的数据了。随着不断有数据写入,master的offset逐渐变大,slave也不断的拷贝,追赶master的offset,直到数组被填满。

  • 如果slave出现网络阻塞(或者宕机等等拥塞),导致master的offset远远超过了slave的offset,如果master继续写入新数据,其offset就会覆盖旧的数据,直到将slave现在的offset也覆盖了(master主节点的offset超过salve从节点的的offset一圈之后)。

  • 那么master就无法完成与 当前的slave 进行增量同步,也就只能重新进行全量同步了。

7.3 主从同步优化

主从同步可以保证主从数据的一致性,非常重要。

可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制(看上去就像零拷贝类似),避免全量同步时的磁盘IO。

  • Redis单节点上的内存占用不要太大,减少RDB导致的过多磁盘IO。

  • 适当提高repl_baklog的大小、发现slave宕机时尽快实现故障恢复、尽可能避免全量同步

  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力

7.4 小结

(1)简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。

  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

(2)什么时候执行全量同步?

  • slave节点第一次连接master节点时

  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

(3)什么时候执行增量同步?

  • slave节点断开又恢复,并且在repl_baklog中能找到offset时

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值