1.复制

1.全量复制

  • 什么时候进行全量复制?

    • 首次和主节点进行数据同步
    • 主节点不方便进行部分复制的时候
  • 全量复制流程

    1. 从节点发送psync命令给主节点进⾏数据同步,由于是第⼀次进⾏复制,从节点没有主节点的运⾏ID和复制偏移量,所以发送psync ? -1
    2. 主节点根据命令,解析出要进⾏全量复制,回复+FULLRESYNC响应
    3. 从节点接收主节点的运⾏信息进⾏保存
    4. 主节点执⾏bgsave进⾏RDB⽂件的持久化
    5. 主节点发送RDB⽂件给从节点,从节点保存RDB数据到本地硬盘
    6. 主节点将从⽣成RDB到接收完成期间执⾏的写命令,写⼊缓冲区中,等从节点保存完RDB⽂件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照RDB的⼆进制格式追加写⼊到收到的rdb⽂件中,保持主从⼀致性
    7. 从节点清空⾃⾝原有旧数据
    8. 从节点加载RDB⽂件得到与主节点⼀致的数据
    9. 如果从节点加载RDB完成之后,并且开启了AOF持久化功能,它会进⾏bgrewrite操作,得到最近的AOF⽂件
      请添加图片描述
  • 注意:全量复制是⼀件⾼成本的操作

    • 主节点bgsave的时间, RDB在⽹络传输的时间,从节点清空旧数据的时间,从节点加载RDB的时间等
    • 所以⼀般应该尽可能避免对已经有⼤量数据集的Redis进⾏全量复制
  • 有磁盘复制 VS 无磁盘复制

    • 默认情况下,进⾏全量复制需要主节点⽣成RDB⽂件到主节点的磁盘中,再把磁盘上的RDB ⽂件通过发送给从节点
    • Redi 从2.8.18版本开始⽀持⽆磁盘复制,主节点在执⾏RDB⽣成流程时,不会⽣成RDB⽂件到磁盘中了,⽽是直接把⽣成的RDB数据通过⽹络发送给从节点,这样就节省了⼀系列的写硬盘和读硬盘的操作开销

2.1部分复制

  • 部分复制主要是Redis针对全量复制的过⾼开销做出的⼀种优化措施
    • 使⽤psync replicationId offset命令实现
  • 什么时候进行部分复制?
    • 当从节点正在复制主节点时,如果出现⽹络闪断或者命令丢失等异常情况时,从节点会向主节点要求补发丢失的命令数据,如果主节点的复制积压缓冲区存在数据则直接发送给从节点, 这样就可以保持主从节点复制的⼀致性
    • 补发的这部分数据⼀般远远⼩于全量数据,所以开销很⼩
  • 部分复制流程
    1. 当主从节点之间出现⽹络中断时,如果超过repl-timeout时间,主节点会认为从节点故障并中断复制连接
    2. 主从连接中断期间主节点依然响应命令,但这些复制命令都因⽹络中断⽆法及时发送给从节点,所以暂时将这些命令滞留在复制积压缓冲区中
    3. 当主从节点⽹络恢复后,从节点再次连上主节点
    4. 从节点将之前保存的replicationId和复制偏移量作为psync的参数发送给主节点,请求进⾏部分复制
    5. 主节点接到psync请求后,进⾏必要的验证,随后根据offset去复制积压缓冲区查找合适的数据, 并响应+CONTINUE给从节点
    6. 主节点将需要从节点同步的数据发送给从节点,最终完成⼀致性
      请添加图片描述

2.2复制积压缓冲区

  • 复制积压缓冲区是保存在主节点上的⼀个固定⻓度的队列,默认⼤⼩为1MB

    • 会记录最近一段时间修改的数据
    • 总量有限,随着时间的推移,就会把之前的旧的数据逐渐删掉
  • 当主节点有连接的从节点(slave)时被创建,这时主节点(master)响应写命令时,不但会把命令发送给从节点,还会写⼊复制积压缓冲区
    请添加图片描述

  • 由于缓冲区本质上是先进先出的定⻓队列,所以能实现保存最近已复制数据的功能,⽤于部分复制和复制命令丢失的数据补救

  • 复制缓冲区相关统计信息可以通过主节点的info replication

    127.0.0.1:6379> info replication
    # Replication
    role:master
    ...
    repl_backlog_active:1                // 开启复制缓冲区
    repl_backlog_size:1048576            // 缓冲区最⼤⻓度
    repl_backlog_first_byte_offset:7479  // 起始偏移量,计算当前缓冲区可⽤范围
    repl_backlog_histlen:1048576         // 已保存数据的有效⻓度
    
  • 根据统计指标,可算出复制积压缓冲区内的可⽤偏移量范围[repl_backlog_first_byte_offset, repl_backlog_first_byte_offset + repl_backlog_histlen]

  • 如果当前从节点需要的数据,已经超出了主节点的积压缓冲区的范围,则⽆法进⾏部分复制,只能全量复制了


3.实时复制

  • 主从节点在建⽴复制连接后,主节点会把⾃⼰收到的修改操作,通过TCP⻓连接的⽅式,源源不断的传输给从节点,从节点就会根据这些请求来同时修改⾃⾝的数据,从⽽保持和主节点数据的⼀致性
  • 这样的⻓连接,需要通过⼼跳包的⽅式来维护连接状态(这⾥的⼼跳是指应⽤层⾃⼰实现的⼼跳,⽽不是TCP⾃带的⼼跳)
    • 主从节点彼此都有⼼跳检测机制,各⾃模拟成对⽅的客⼾端进⾏通信
    • 主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活性和连接状态
    • 从节点默认每隔1秒向主节点发送replconf ack {offset}命令,给主节点上报⾃⾝当前的复制偏移量
  • 如果主节点发现从节点通信延迟超过repl-timeout配置的值(默认60秒),则判定从节点下线,断开复制客⼾端连接
    • 从节点恢复连接后,⼼跳机制继续进⾏

2.总结

  • 单点问题
    • 单个Redis节点,可用性不高
    • 单个Redis节点,性能有限
  • 主从复制的特点
    • Redis通过复制功能实现主节点的多个副本
    • 主节点⽤来写,从节点⽤来读,这样做可以降低主节点的访问压⼒
    • 复制⽀持多种拓扑结构,可以在适当的场景选择合适的拓扑结构
    • 复制分为全量复制,部分复制和实时复制
    • 主从节点之间通过⼼跳机制保证主从节点通信正常和数据⼀致性
  • 主从复制配置的过程
    • 主节点配置不需要改动
    • 从节点在配置⽂件中加⼊slaveof 主节点ip 主节点端口的形式即可
  • 主从复制的缺点
    • 从机多了,复制数据的延时⾮常明显
    • 主机挂了,从机不会升级成主机,只能通过⼈⼯⼲预的⽅式恢复
Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐