Redis的复制

Redis 的复制

概述

分布式系统中为了解决单点问题,通常会把数据复制多个副本部署到其他机器,满足故障处理和负载均衡等功能

配置

建立复制

  1. 在配置文件中加入 slaveof {masterHost} {masterPort} 启动Redis 生效
  2. 在redis-server启动 命令后加上 --slaveof {masterHost} {masterPort} 生效
  3. 直接使用命令 slaveof {masterHost} {masterPort}生效

断开复制

slaveof 命令不但可以建立复制,也可以断开复制,执行slaveof no one 来断开复制 断开复制后并不会抛弃原有数据,只是再也无法获取主节点上的数据变化

拓扑

Redis的复制拓扑结构可以支持单层或多层复制关系:一主一层,一主多层,树状主从结构

  1. 一主一层结构

  2. 一主多层

  3. 树状主从结构

原理

复制过程

  1. 保存主节点信息 ,执行saveof后从节点保存主节点的地址信息后直接返回
  2. 从节点内部通过每秒运行的定时任务维护复制相关逻辑,当任务发现存在新的主节点之后,会尝试简历网络连接(建立socket套接字)
  3. 发送ping命令,检测主从之间套接字是否可用,检测主节点当前是否可接受处理命令
  4. 权限验证,验证密码等一些东西
  5. 同步数据集,主从复制连接首次正常通过后,主节点会把所有的数据发送给从节点 这部分操作是最耗时的
  6. 命令持续复制。主节点同步数据给从节点后,会持续吧命令发送给从节点,保证主从数据一致性

数据同步

全量复制 :一般用于初次复制场景,把主节点数据全部一次发送给从节点,会对主从节点网络造成很大的开销

部分复制 :用于处理在从主之间网络闪断,数据丢失的场景

  1. 复制偏移量。参与复制的主节点会维护自身偏移量,主节点在处理完写入命令之后,会把命令的字节长度做累加记录,从节点每秒上报自身的复制偏移量给主节点
  2. 复制积压缓冲区。复制挤压缓冲区是保存在主节点上的宇哥固定长度的队列,当主节点有连接的从节点时被创建,从节点相应写命令时,不但会把命令发送给从节点,也会写入复制积压缓冲区,用于部分复制和复制命令丢失的数据补救
  3. 主节点运行ID。每个Redis节点启动后都会动态分配一个40位的十六进制字符串作为运行ID。运行ID的主要作用是用来唯一识别的Redis节点
  4. psync命令。从节点使用psync 命令完成部分复制和全复制功能

全量复制

流程图:

  1. 发送psync 命令进行数据同步,第一次复制从节点没有复制偏移量和主节点运行ID 所以发送 psync?-1
  2. 主节点根据1中的命令 解析为全量复制 回复 +FULLRESYNC
  3. 从节点接受主节点的相应数据保存ID 和 偏移量
  4. 主节点执行bgsave 保存RDB文件到本地
  5. 主节点发送RDB文件给从节点
  6. 从节点接收RDB快照期间,主节点仍然响应读写命令,把命令写入复制客户端缓冲区中,主节点再把缓冲区数据发送给从节点,保证主从数据一致性
  7. 从节点接受完主节点的全部数据后会清空自身旧数据
  8. 清空数据后开始加载接收的RDB文件
  9. 加载完RDB文件后 开启AOF持久化 做bgrewriteaof 操作

部分复制

流程图:

  1. 当主从节点之间网络出现中断时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接.
  2. 主节点连接中断期间,主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在复制积压缓冲区,依然可保存最近一段时间的数据,默认为1MB.
  3. 当从节点网络恢复后,从节点会在此连上主节点.
  4. 当主从连接恢复后,因为之前从节点保存了自身已复制的offset和运行ID,所以会把把其当作psync参数发给主节点.
  5. 主节点连接到psync命令后,首先核对参数runId是否一致,如果一致说明之前复制的是当前主节点,然后根据offset参数在自身复制积压缓冲区中进行查找,如果偏移量之后的数据存在缓冲区中,则想从节点发送 +CONTINUE 响应,表示进行部分复制.
  6. 主节点根据偏移量吧复制积压缓冲区里数据发给从节点,以保证主从复制进入正常状态.

心跳

  1. 主从节点彼此都有心跳检测机制,各自模拟成对方的客户端急性通信,通过 client list 命令查看复制相关客户端信息,主节点的连接状态为 flags = M,从节点的连接状态是 flags = S.
  2. 主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活状态和连接状态,可通过修改配置 repl-ping-slave-period 控制发送频率.
  3. 从节点在主线程每隔1秒发送 replconf ack{offset} 命令,给主节点上报自身当前的复制偏移量.
  4. 主节点收到 replconf 信息后,判断从节点超时时间,如果超过 repl-timeout 设置的值(默认值为60 秒),则判断从节点下线,并断开复制客户端连接.

异步复制

主节点不但负责数据读写,还负责把写命令同步给从节点.写命令的发送过程是异步完成的,也就是说主节点自身处理完写命令后直接返回给客户端,并不等待从节点复制完成,如下图所示:

异步复制的流程如下:

  1. 主节点接受处理命令
  2. 命令处理完之后返回响应结果
  3. 对于修改命令异步发送给从节点,从节点在主线程中执行复制的命令.
posted @ 2019-07-16 22:49  dingyl  阅读(239)  评论(0编辑  收藏  举报