zoukankan      html  css  js  c++  java
  • SLAVEOF以后

      当我们想要某个Redis服务器复制另一个服务器时,我们可以在连接这个Redis服务器的客户端上输入“SLAVEOF”命令指定另一个服务器的IP地址和端口号:
      SLAVEOF <master_ip> <master_port>。
      执行成功之后,这个服务器就成为指定服务器的从服务器,指定的服务器则是这个服务器的主服务器,从服务器会同步并复制主服务器的所有数据,与主服务器的数据库状态保持一致。本文要讲的就是2.8版本以后的Redis在客户端“SLAVEOF”命令输入回车以后都发生了什么。

    1. 设置主服务器的地址和端口
      根据“SLAVEOF”命令中指定的IP地址和端口号,设置当前服务器(从服务器)状态中的主服务器地址属性“masterhost”和主服务器端口属性“masterport”:

      设置完成之后,便向客户端返回“OK”,而实际的复制工作则是在返回“OK”以后才开始执行的,即,“SLAVEOF”是一个异步命令。

    2. 建立套接字连接
      从服务器根据“SLAVEOF”命令中指定的IP地址和端口号,创建连向主服务器的套接字连接。
      连接成功之后,从服务器将为这个套接字关联一个文件事件处理器,专门用于处理复制工作,比如,接收主服务器传送的RDB文件和写命令。
      而主服务器则为该套接字创建相应的客户端状态,并将从服务器当作一个连接到主服务器的客户端来对待。

    3. 发送PING命令
      从服务器成为主服务器的客户端之后,做的第一件事就是向主服务器发送一个“PING”命令。作用有二:
    (1)检查套接字的读写状态是否正常;
    (2)检查主服务器能否正常处理命令请求。
      从服务器发送“PING”命令可能遇到的情况如下图所示:

    4. 身份验证
      如果从服务器设置了“masterauth”选项,则需要向主服务器发送“AUTH”命令进行身份验证:
      AUTH <“masterauth”选项配置的值>。
      主服务器接收到“AUTH”命令发送的密码之后,将其与自身的“requirepass”选项设置的密码进行对比,来决定身份验证是否通过。
      整个流程如下图所示:

    5. 发送端口信息
      从服务器向主服务器发送从服务器的监听端口号:
      REPLCONF listening-port <port_number>
      主服务器接收到以后将其记录在从服务器对应的客户端状态中:

      该属性目前唯一的作用:在主服务器执行“INFO replication”命令时打印出从服务器的端口号。

    6. 数据同步
      Redis2.8版本以后的数据同步有两种方式:完整重同步和部分重同步。其中完整重同步与Redis2.8版本之前的方法一样,都是使用RDB文件;而部分重同步是Redis2.8版本之后引入的,为了实现部分重同步还需要引入复制偏移量和复制积压缓冲区两个概念:
    (2)复制偏移量:执行复制的双方——主服务器和从服务器都会分别维护一个复制偏移量,可以通过对比双方的偏移量来确认是否处于一致状态。复制偏移量实质上是指当前服务器复制数据在复制积压缓冲区中的位置。
    (1)复制积压缓冲区:这是主服务器维护的一个先进先出的队列,长度固定,默认为1MB,保存着主服务器最近执行的一部分写命令,并为队列中的每个字节记录相应的复制偏移量。
      所以,当主服务器进行命令传播时,它不仅会将写命令发送给所有从服务器,还会将写命令入列到复制积压缓冲区里面:

      开始数据同步时,从服务器根据自身情况向主服务器发送“PSYNC”命令:
    (1)初次复制(以前没有复制过任何主服务器):PSYNC ? -1
    (2)非初次复制(以前有复制过某个主服务器):PSYNC <runid> <offset>(“runid”为主服务器运行ID,“offset”为从服务器的复制偏移量)
      主服务器收到“PSYNC”命令之后,首先判断其中的“runid”是否与自身运行ID一致,若不一致则采取完整重同步操作;若一致则进一步判断“offset”,如果偏移量为“offset”之后的数据存在于复制积压缓冲区中则采取部分重同步操作,否则采取完整重同步操作。若决定采取完整重同步操作,主服务器将返回“+FULLRESYNC <runid> <offset>”,将自己的运行ID和当前复制偏移量发送给从服务器,从服务器则将主服务器的运行ID保存起来,用于下一次执行“PSYNC”命令时作为参数,同时将主服务器当前复制偏移量作为自己的初始化偏移量;若决定采取部分重同步操作,主服务器返回“+CONTINUE”,从服务器等待接收并执行主服务器发送的写命令即可。
      整个流程如下图所示:

      完整重同步和部分重同步的实现过程如下:
    (1)完整重同步:
      主服务器执行“BGSAVE”命令,在后台生成一个RDB文件,同时使用一个缓冲区记录在开始生成RDB文件那一刻之后执行的所有写命令。
      主服务器将生成的RDB文件发送给从服务器,从服务器接收并载入这个RDB文件来更新自己的数据库状态。
      主服务器将记录在缓冲区中的所有写命令也发送给从服务器,从服务器执行这些写命令之后,主从服务器的状态就一致了。
    (2)部分重同步:
      主服务器根据从服务器的复制偏移量,在复制积压缓冲区中找到对应位置,将缓冲区中该位置之后的所有写命令数据都发送给从服务器,从服务器执行这些写命令之后,主从服务器的状态就一致了。

    7. 命令传播
      主从服务器数据同步完成以后,主服务器只要一直将自己执行的写命令发送给从服务器,从服务器则一直接收并执行主服务器发送来的写命令,主从服务器就可以一直保持一致了。
      除此之外,从服务器还会默认以每秒一次的频率,向主服务器发送命令:
      REPLCONF ACK <replication_offset>(“replication_offset”为从服务器自身的复制偏移量)
      此命令是Redis2.8版本之后引入的,用于心跳检测,作用有三:
    (1)检测主从服务器的网络连接状态
      “INFO replication”命令在列出的从服务器列表的“lag”一栏中记录了对应的从服务器最后一次向主服务器发送“REPLCONF ACK”命令距离现在过了多少秒,若超过1秒则说明主从服务器连接已经出现故障。
    (2)辅助实现“min-slaves”配置选项
      “min-slaves-to-write”和“min-slaves-max-lag”两个选项的配置是为了防止主服务器在不安全的情况下执行写命令,例如:
      min-slaves-to-write 3
      min-slaves-max-lag 10
      那么在从服务器的数量少于3个,或者至少存在3个从服务器的延迟值都大于或等于10秒时,主服务器将拒绝执行写命令。这里的延迟值就是就是“INFO replication”命令中列出的从服务器列表的“lag”一栏中记录的值。
    (3)检测命令丢失
      如果因为网络故障,主服务器传播给从服务器的写命令在半路丢失了。主服务器可以通过将自己的复制偏移量和从服务器在“REPLCONF ACK”命令中发送的偏移量进行比较来发现这一问题,然后在复制积压缓冲区中找到从服务器缺少的数据,并将这些数据重新发送给从服务器。

    8. 断线重连
      当某个从服务器断线了,重新连上主服务器之后,从服务器需要重新发送“PSYNC”命令给主服务器,重新跑一遍第6步中的逻辑。其中主服务器需要根据从服务器的情况决定数据同步要采取完整重同步还是部分重同步,而完整重同步不论对于主服务器还是从服务器而言都是十分耗费资源的,所以我们当然希望断线重连的情况中尽可能多地进行部分重同步而不是完整重同步,这就需要合理设置主服务器的复制积压缓冲区的大小了。
      为了保证绝大部分断线重连情况都能使用部分重同步来处理,复制积压缓冲区的大小可以设置为:
      2 * 从服务器断线重连所需平均时间(秒) * 主服务器每秒产生的写命令数量

  • 相关阅读:
    微软Silverlight团队关于PDC会议发表官方补充声明(风云翻译版)
    《银光志Silverlight 3.0开发详解与最佳实践》发行第三版总销量过万册
    Silverlight医学PACS诊断分析管理系统【案例分享】
    微软PDC10与最后的恐慌者
    风云的银光志Silverlight4.0教程之与学会使用Frame控件
    WPF案例之生产线控制器管理系统
    WindowsPhone7 经典3D游戏《刺客信条》评测
    Silverlight4开发的炫酷企业网站整站(运行大量特效)
    微软Windows Phone7超越Android、iOS的五大优势
    as3 滤镜学习笔记
  • 原文地址:https://www.cnblogs.com/wujuntian/p/9265622.html
Copyright © 2011-2022 走看看