zoukankan      html  css  js  c++  java
  • Redis 的主从同步(复制)

    Redis 的主从同步(复制)

    Redis 的主从同步(复制)

    什么是主从同步(复制)

    假设有两个 redis 实例 ⇒ A 和 B

    B 实例的内容与 A 实例的内容保持同步

    那么称 A 实例是主数据库,B 实例是从数据库

    这个过程称为主从同步

    为什么要使用主从同步(复制)

    1. 防止发生单点故障
    1. 扩展内存

    如何开启/关闭主从同步

    开启同步

    • 配置文件中加入
    slaveof 主数据库地址 主数据库端口
    • 在命令行中执行上述命令
    redis> slaveof 主数据库地址 主数据库端口
    • 在开启从服务器时执行命令
    $ reids-server --port 6380 --slaveof 主数据库地址 主数据库端口

    关闭同步,并成为主数据库

    redis> slaveof no one

    原理(实现)

    复制分为连接建立,数据同步(sync)和命令传播(command propagate)三个阶段

    连接建立这里不说,与复制原理无关

    下面主要讲数据同步与命令传播两个阶段

    redis 从 2.8 版本之后优化了复制功能,咱们先从旧版本的复制说起:

    旧版复制过程

    步骤主服务器从服务器
    同步流程    
    1   向主服务器发送 SYNC 命令
    2 收到 SYNC 命令,执行 BGSAVE 生成 RDB 文件  
    3 使用缓冲区记录从现在的写命令  
    4 将生成的 RDB 文件发送给从服务器  
    5 将缓冲区内的写命令发给从服务器 接收并载入 RDB 文件
    6   接收并执行主服务器发送来的写命令
    命令传播流程    
    1 发送客户端发过来的写命令  
    2   执行主服务器发送过来的写命令
    断线重连 与同步流程一致 与同步流程一致

    经过上述步骤之后主从服务器的状态可以始终保持一致。

    细心的读者已经发现了旧版复制的一些问题:

    断线重连需要重新走一次同步的流程,而同步流程中的主服务器生成 RDB 文件和从服务器执行 RDB 文件都是特别密集的 IO 操作,这会让断线重连的成本很高

    于是从 2.8 版本之后,redis 使用了新的技术来防止重新执行同步流程

    新版复制过程

    步骤主服务器从服务器
    完整同步流程    
    1   向主服务器发送 PSYNC 命令
    2 收到 PSYNC 命令,执行 BGSAVE 生成 RDB 文件  
    3 使用缓冲区记录从现在的写命令  
    4   接收并执行主服务器发送来的写命令
    5 将缓冲区内的写命令发给从服务器 接收并载入 RDB 文件
    6 将生成的 RDB 文件发送给从服务器  
    命令传播流程    
    1 发送客户端发过来的写命令  
    2   执行主服务器发送过来的写命令
    断线重连过程    
    1   发送 PSYNC 命令
    2 向从服务器发送断线过程中的写命令  
    3   执行写命令

    新版复制经过上述步骤,也可以实现主从数据库状态的一致。

    在断线重连过程中,只需要重新执行断线过程中未同步的命令即可,这样就比旧版的复制节省了很多 IO 操作

    那么这个断线重连的是怎么实现的呢?

    部分重同步(断线重连)的实现

    redis 的部分重同步借助了4个变量:

    1. 服务器的运行 ID (run ID)
      • 当实例重启时,会生成40个随机的十六进制字符
    1. 主服务器的复制积压缓冲区(replication backlog)
      • 主服务器每将一个命令传送给从数据库,都会将命令放到一个积压队列(固定长度的循环队列)中
    1. 主服务器的复制偏移量(replication offset)
      • 主服务器将命令放到积压队列中时,会记录下当前命令的偏移量,并发送给从服务器
    1. 从服务器的复制偏移量
      • 从服务器接收到主服务器发送过来的命令与偏移量

     

    也许将这4个变量列出来之后,有读者就可以直接想象出来是怎么实现的了,对,没错,就是这么实现的

    过程:

    部分重同步流程

    步骤主服务器从服务器
    1   发送命令 PSYNC 主数据库的运行ID 断开前最新的命令偏移量
      判断 1. 运行ID是否能够对应 2. 断开前最新的命令偏移量是否在队列中 满足上述条件可以执行部分重同步,否则执行完全同步  
    2 发送给从数据库偏移量之后的命令  
    3   执行命令

    总结

    redis 在很多细节上优化了性能,主从同步(复制)的优化只是其中的一方面。

  • 相关阅读:
    第一个Java程序
    kibana 创建index pattern 索引模式时过慢导致无法创建成功 以及解决方案
    各种推导式
    生成器表达式
    生成器函数进阶
    迭代器和生成器
    pyhton 监听文件输入实例
    window 日志清除
    window iis重启
    TCP/IP四层模型
  • 原文地址:https://www.cnblogs.com/wudanyang/p/11623543.html
Copyright © 2011-2022 走看看