redis全量复制的原理是,首先将master自己的RDB文件同步给slave,而在同步期间,master写入的命令也会记录下来(master内部有一个复制缓冲区,会记录同步时master新增的写入),当slave将RDB加载完后,会经过偏移量的对比将这期间master写入的值同步给slave。redis
来看一张完整的复制流程图:缓存
1. slave内部首先会发送一个psync的命令给master 这个命令第一个参数是runId,第二个参数是偏移量,而因为是第一次复制,slave不知道master的runId,也不知道本身偏移量,这时候会传一个问号和-1,告诉master节点是第一次同步。网络
2. 当master接受到psync ? -1 时,就知道slave是要全量复制,就会将本身的runID和offset告知slavespa
3.slave会将master信息保存队列
4.master这时会作一个RDB的生成(bgsave)进程
5.将RDB发送给slave内存
6.将复制缓冲区记录的操做也发送给slave同步
7.slave清空本身的全部老数据ast
8.slave这时就会加载RDB文件以及复制缓冲区数据,完成同步。原理
1.bgsave的开销,每次bgsave须要fork子进程,对内存和CPU的开销很大
2.RDB文件网络传输的时间(网络带宽)
3.从节点清空数据的时间
4.从节点加载RDB的时间
5.可能的AOF重写时间(若是咱们的从节点开启了AOF,则加载完RDB后会对AOF进行一个重写,保证AOF是最新的)
为何要部分复制? 在redis2.8版本以前,若是master和slave之间的网络发生了抖动链接断开,就会致使slave彻底不知道master的动做,同步就会出问题,而为了保证数据一致,等网络恢复后进行一次全量复制。而全量复制的开销是很大的,redis2.8版本就提个了一个部分复制的功能。
部分复制的实现原理:
当master和slave断开链接时,master会将期间所作的操做记录到复制缓存区当中(能够当作是一个队列,其大小默认1M)。待slave重连后,slave会向master发送psync命令并传入offset和runId,这时候,若是master发现slave传输的偏移量的值,在缓存区队列范围中,就会将从offset开始到队列结束的数据传给slave,从而达到同步,下降了使用全量复制的开销。