主从复制,是把一台redis服务器上数据复制到其余服务器的机制,其中前者被称为主节点(master),后者被称为从节点(slave)。html
主从复制的主要主要做用:node
默认状况下,每一个redis服务器都是master节点,每个master能够有多个slave节点,可是一个salve节点只能有一个master节点。redis
准备节点算法
默认6380端口做为master节点,再启动一个6380节点做为salve节点。服务器
复制一个配置文件,命名为redis6380.conf网络
配置新的端口号负载均衡
两个redis实例已经启动。socket
执行复制命令tcp
启动两个实例优化
执行slaveof命令
查看效果
master节点写入,读取
slave节点读取数据
至此,复制搭建成功,数据已经成功从master复制到了slave,而且经过salve读取成功。
直接使用slaveof no one命令便可断开和master的复制关系
断开复制关系后的数据
能够看到原有的数据保留了
断开后在原有master写入
数据将再也不同步到6380
能够经过切换到其余master的方式断开和当前master的绑定。可是和slave no one不一样的是,切换新的master后,从原有master复制过来的数据会被清空。
一对一,一对多,树状结构。
4.1保存主节点
执行slaveof后从节点只是保存了主节点的地址信息变直接返回,复制流程尚未正式开始。
4.2 主从创建socket链接
从节点内部经过每秒运行的定时任务来处理相关逻辑,当定时任务发现存在新的主节点后,会尝试和主节点创建网络链接。
从节点会建立一个socket去链接主节点,后续数据同步都是基于这个socket进行。
若是从节点没法创建链接,定时任务会无限重试到链接成功或者复制被取消为止。
4.3 发送ping命令
链接创建成功后从节点会向主节点发送ping请求进行首次通讯,主要有以下目的:
发送ping命令后若是从节点没有收到pong回复或者超时(好比网络超时,或者主节点阻塞没法处理等),从节点会断开复制,下次定时任务发起后从新链接。
4.4 权限验证
若是主节点设置了requirepass参数,则须要密码验证,从节点必须配置masterauth参数保证与主节点相同的密码才能经过验证,若是验证失败,从节点会断开复制,下次定时任务发起后从新链接。
4.5 数据同步
主从复制链接创建成功后,便开始数据同步,属于数据的初始化,主节点会把持有的全部数据发送给从节点,主题是实现方式是从节点给主节点发送psync命令(2.8以前是sync命令)。这块是耗时最长的步骤,分为全量同步和部分同步。
4.6 命令持续同步
当主节点把当前的数据同步给从节点后,便完成了复制的创建流程,后续主节点会持续的把命令发送给从节点,保证主从一致。
主从创建链接成功后,从节点会向主节点发送psync命令来完成数据同步,同步过程分为:全量复制和部分复制。
psync命令运行须要如下组件的支持:
master节点处理完写入命令后,会把命令的字节长度作累加记录。
从节点再接收到主节点发送的命令后,也会累加自身的偏移量。
经过对比master的偏移量和slave的偏移量来看slave和master的数据差别大小。
复制缓冲区是保存在主节点上的一个固定长度队列,默认大小为1MB,当有slave时候回建立缓冲区,这时主节点响应写命令时,不但会把命令发送给从节点,还会写入复制挤压缓冲区。
挤压缓冲区是一个先进先出的队列,若是超过容量,以前的数据会被覆盖。大小是能够配置的。挤压缓冲区主要为了部分复制作准备。能够经过info replication来查看:
repl_backlog_active:1 //开启复制缓冲区 repl_backlog_size:1048576 //缓冲区最大长度 repl_backlog_first_byte_offset:4505 //起始变异量,计算当前缓冲区可用范围 repl_backlog_histlen:5460 //已保存数据的有效长度
每一个redis节点(主从)启动后都会生成一个40位的16进制的字符串做为运行id,用于惟一识别一个redis节点。从节点会保存主节点的运行id用于识别本身正在复制的是哪个主节点。redis重启后id会改变。
初次复制时,从节点会保存主节点的runid。
从节点经过给主节点发送psync命令实现部分复制或者全量复制。命令格式为:
psync {runid} {offset}
第一次复制时没有offset和主节点的runid,会发送psync -1命令
部分复制时redis针对全量复制开销太高作出的一种优化措施,使用psync {runid}{offset}命令实现。
当主从复制的过程当中,若是出现网络闪断或者命令丢失等异常状况,从节点会要求主节点补发数据,若是此时主节点的复制积压缓冲区内存中恰好存在这部分数据(就是断网这段时间没有同步到从节点的数据),则直接发给从节点,最终保持了和从节点的一直,也避免了大规模的全量复制。
主节点判断判断知足部分复制的条件
若是不知足部分复制条件,则主节点会返回fullsync给从节点,从节点会开启全量复制。
因而可知复制积压缓冲区的大小比较重要,若是过小,会被覆盖,最终致使主从网络恢复后没法进行部分复制,这个值得大小应该要基于网络的中断时间,已经主节点的qps和命令的大小来进行计算,而后进行合理的设置。
主从心跳检测示意图
master会周期性的ping slave,周期时间经过repl-ping-replica-period参数来控制,默认是10秒
slave每隔1秒回向master发送replconf ack {offset}命令:
实时监测主从节点的网络状态
上报自身的数据复制偏移量,若是主节点发现从节点有数据缺失,主节点会从自身的复制积压缓冲区中拉取数据发给从节点。
实现从节点的数量和延迟性功能,经过min-replicas-to-write(最小可用的从节点个数)和min-replicas-max-lag(容许的最小延迟秒,通常为0,或者1)参数定义。
若是master开启了这两个参数,那么若是可用的从节点小于min-replicas-to-write或者延迟大于min-replicas-max-lag,master会拒绝数据写入。示意图以下。
redis.conf有个repl-timeout参数:
slave角度,若是在repl-timeout时间内没有收到传输的rdb snapshot数据,
slave角度,若是在repl-timeout没有收到master发送的数据包或者ping。
master角度,若是在repl-timeout时间没有收到REPCONF ACK确认信息。
当redis检测到repl-timeout超时(默认值60s),将会关闭主从之间的链接,redis slave会从新创建主从链接的请求。这个值必定要大于repl-ping-replica-period参数
为了下降主从延迟,通常建议把redis的主从节点部署在相同的机房。
全量复制很是重,应该尽可能避免,下面是一些会致使全量复制的操做。