上一篇文章redis 之复制-初入江湖中,讲了关于redis复制配置,如:如何建立配置、如何断开复制、关于链接的安全性等等,那么本篇文章将深入的去说一下关于redis复制原理,如下:
在从节点执行slaveof命令后,复制过程便开始运作,下面将会详细的讲解建立复制的完整流程,如下图所示:
从上图中,可以看出复制的一个大致流程:
在上面的复制整个流程中,有一个步骤是“同步数据集”,这个通过过程分为:全量复制和部分复制.
全量复制:一般用于初次复制场景,redis早期支持的复制功能便只有全量复制,它会把主节点的所有数据一次性发给从节点,当数据量较大时,这会给主从节点之间的各个方面带来很大的开销.
部分复制:用于处理在主从复制中因网络闪断等原因造成数据丢失的场景,当从节点再次连上主节点后,如果条件允许,主节点会补发之前丢失的数据给从节点.因为补发的数据远远小于全量数据,可以有效的避免复制过程中的过高开销.
redis的同步有2个命令,分别是:sync 和 psync,前者是 redis 2.8 之前的同步命令,后者是 redis 2.8 为了优化 sync 新设计的命令.我们会重点关注 2.8版本以后的 psync 命令.psync 命令的运行需要三个组件支持:(1)主从节点各自复制偏移量;(2)主节点复制积压缓冲区;(3)主节点运行id.
1.参与复制的主从节点都会维护自身复制偏移量.统计信息在使用info replication命令查看中的master_repl_offset指标中.
2.从节点(slave)每秒钟上报自身复制偏移量给主节点,因此主节点也会保存从节点的偏移量.
3.从节点在接收到主节点发送的命令后,也会累加自身的偏移量.
4.通过对比主从节点的复制偏移量,可以判断主从节点数据是否一致,如下图所示.
注:可以通过主节点的统计信息,计算出master_repl_offset-slave_offset字节量,判断主从节点复制相差的数据量,根据这个产值判定当前复制的健康度.如果主从之间复制偏移量相差较大,则可能是网络延迟或命令阻塞等原因引起的.
(1)复制积压缓冲区是保存在主节点上的一个固定长度的队列,默认大小为1mb.当主节点有连接的从节点(slave)被创建时,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区,如下图所示.
(2)由于缓冲区本质上是先进先出的定长队列,所以能实现保存最近已复制数据的功能,用于部分复制和复制命令丢失的数据补救,可以通过 info replication 查看相关信息.
(1)每个redis节点启动后都会动态分配一个40位的十六进制字符串作为运行id.
(2)运行id的主要作用是用来唯一识别的redis节点,比如从节点保存主节点运行id识别自己正在复制的是哪个主节点.如果只是使用ip+port的方式识别主节点,那么主节点重启变更了整体数据集(如替换rdb/aof文件),从节点再基于偏移量复制数据将是不安全的,因此当运行id变化后从节点将做全量复制.
(3)上面提到的是主节点重启变更,那么重启不改变运行id呢?这时可以使用 debug reload 命令重新加载rdb并保持运行id不变,从而有效避免不必要的全量复制.
注:debug reload命令会阻塞当前redis节点主线程,阻塞期间会生成本地rdb快照并清空数据之后再加载rdb文件.因此对于大量数据的主节点和无法容忍阻塞的应用场景,是要谨慎使用的.
从节点使用psync命令完成部分复制和全量复制功能.命令格式:psync {runid} {offset},其参数含义如下:
psync的执行流程如下:
流程说明:
全量复制是redis最早支持的复制方式,也是主从第一次建立复制是必须要走的流程.触发全量复制的命令是 sync 和 psync.前面已经说过,redis 2.8 之前使用 sync 只能执行全量不同, 之后同时支持全量同步和部分同步.
流程如图:
流程说明:
以上加粗的部分是整个全量同步耗时的地方.
注:
部分复制主要是redis针对全量复制的过高开销,所做的一些优化.在slave(从节点)正在向master(主节点)时,如果出现网络闪断或者命令丢失等异常情况发生时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区内存在这部分,则直接打给从节点,这样便可以保持主从节点复制的一致性.补发的这部分数据远远小于全量数据,所以开销很小.部分复制流程图如下:
主从节点在建立复制后,他们之间维护着长连接,并且彼此发送心跳.如图:
主从心跳判断机制:
replconf的作用:
- 实时监测主从节点的网络状态
- 上报自身的偏移量,检查复制数据是否丢失
- 实现保证从节点的数量和延迟功能,通过min-slaves-to-write,min-slaves-max-lag参数配置定义
注意:为了降低主从延迟,一般把 redis 主从节点部署在相同的机房/同城机房,避免网络延迟带来的网络分区造成的心跳中断等情况.
主节点不但负责数据读写,还负责把写命令同步给从节点.写命令的发送过程是异步完成的,也就是说主节点自身处理完写命令后直接返回给客户端,并不等待从节点复制完成,如下图所示:
异步复制的流程如下:
本篇文章,大略分析了下复制过程、数据同步、全量复制、部分复制、心跳、异步复制等方面的原理.
参考:《redis开发与运维》
版权声明:尊重博主原创文章,转载请注明出处 https://www.cnblogs.com/hsdy
如对本文有疑问, 点击进行留言回复!!
MongoDB中数据的替换方法实现类Replace()函数功能详解
理解Redis持久化,RDB持久化和AOF持久化的不同处理方式
网友评论