【Redis】主从复制

内容有点潦草,后续修订,见谅。

为主节点做数据备份,也可提供数据查询服务,缓解主节点读写压力,也是实现高可用和故障恢复的必要内容。

特点

  • Redis使用异步复制,确认处理的数量
  • 一主多从复制
  • 从v4.0起,副本可继续进行主从复制,即从从复制
  • 在主节点上,复制是非阻塞的,复制与查询可同时进行
  • 在从节点,复制也是非阻塞的,当完成初始化同步后,可以查询历史数据
    • 但需要尽快删除历史数据,并加载新数据,这个期间会锁定连接池,可能需要花费几秒
    • v4.0起,支持删除数据和加载数同步执行(不同线程)
  • 复制也是有扩展性的,可以为只读查询提供多个副本
  • 使用复制避免主节点写入整个数据集到磁盘的成本

复制机制

  • 通过stream命令复制全部数据效果
  • 当主节点和副本通信中断后又恢复通信时,需要进行部分重新同步
  • 当部分重新同步不可能时,会要求重新同步

复制方式

  • 异步复制,默认方式
  • 同步方式,通过WAIT命令实现

复制逻辑

核心:这些信息用于标记主库的确切数据版本

  • 复制ID:主节点有一个复制ID,有大量随机字符串组成,标记一个给定的数据集仓库。
  • 增长偏移量:主节点也会制作一个复制stream的增长偏移量,然后发送给副本,去更新副本新修改的数据集的状态。

复制流程

  1. 副本连接主节点,并使用PSYNC命令发送旧的复制ID和偏移量
  2. 主节点接收到连接请求,校验复制ID和偏移量
    1. 若匹配到指定的复制ID,则进行数据增量同步(以命令流形式)
    2. 若未在历史中找到匹配的复制ID,或者缓冲区没有足够的backlog,触发全量同步(完整复制)

完整复制

  1. 主节点在后台启动保存进程以生产RDB文件,同时页缓存客户端接收到的所有新写入命令
  2. 当后台保存完成,主节点传输数据文件(RDB文件)到副本
  3. 副本接收到数据文件后,需要将其保存到磁盘,然后加载它到内存
  4. 然后,主节继续将缓存的所有命令同步给副本,
  5. 这些工作是以命令流形式完成的,与redis协议格式相同

SYNC协议

  1. 连接正在工作的redis服务器
  2. 发送SYNC命令,可以看到批量传输,服务器接收到的每个命令都会在会话上输出显示
  3. SYNC是旧协议,已经不再被使用,但可以向下兼容
  4. 因为SYNC不能进行局部复制,因此被PSYNC替代

自动重连

  • 当主节点和副本之间因一些原因下线后,副本能够自动重连。
  • 如果主节点接收到多个并发副本同步请求,将执行一个单独的后台保存以服务这些请求。

复制ID

  • 一个复制ID可以标记数据集的历史,
  • 当主节点重启,或副本被提升主节点后复制ID会重新生成。
  • 相同的复制ID,代表拥有相同的数据,但可能处于不同时间,偏移量代表最新数据集

故障恢复复制:存在两个复制ID

  1. 当副本被提升为主节点后,记住过去的复制ID,用于当其他副本与新主节点复制同步时,尝试使用旧的复制ID进行重新同步
  2. 新主节点将旧复制ID设置为辅助复制ID(二级复制ID),并记住切换复制ID时的偏移量,生成新的随机复制ID,开始新的历史记录
  3. 当处理其他副本连接时,新主节点将用当前的复制ID和辅助辅助ID匹配他们的复制ID和偏移量,进行数据复制,这样副本就不必再执行完全同步。

无磁盘复制

通常完整复制需要通过在磁盘上创建RDB文件来实现。但慢磁盘会使操作变得糟糕。

v2.8.18开始,支持无盘复制。子进程通过网络将RDB文件内容直接发送给副本,而不在磁盘上存储。

只读副本

只允许客户端在副本上进行只读操作,不能写入。

replica-read-only

限制副本

v2.8起,可以配置主节点只写入查询条件。避免同时复制对主节点的客户端写命令造成压力。

  • Redis复制每秒钟ping一次主机,确认处理的复制流的数量。
  • Redis的主节点会记得最后一次收到来自每个副本的ping。
  • 用户可以配置延迟不大于最大秒数的最小副本数量。
min-replicas-to-write <number of replicas> # 最小副本数量
min-replicas-max-lag <number of seconds> # 延迟时间

过期Key处理

实现方式:

  • 副本不过期Keys,当master过期Keys时,通过同步del删除命令给所有副本
  • 客户端请求过期Keys时,副本返回不存在,即使存在逻辑Keys
  • lua脚本执行时,不会执行Keys过期

实践

暂略

你可能感兴趣的:(redis,主从复制)