当我们想要某个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 * 从服务器断线重连所需平均时间(秒) * 主服务器每秒产生的写命令数量

SLAVEOF以后的更多相关文章

  1. windows下Redis主从复制配置(报错:Invalid argument during startup: unknown conf file parameter : slaveof)

    主从复制配置中的遇到的异常: Invalid argument during startup: unknown conf file parameter :  slaveof 把Redis文件夹复制两份 ...

  2. Redis的 SLAVEOF 命令

    SLAVEOF host port SLAVEOF 命令用于在 Redis 运行时动态地修改复制(replication)功能的行为. 通过执行 SLAVEOF host port 命令,可以将当前服 ...

  3. windows环境redis主从安装部署

    准备工作 下载windows环境redis,我下载的是2.4.5,解压,拷贝一主(master)两从(slaveof).主机端口使用6379,两从的端口分别为6380和6381, 我本地索性用6379 ...

  4. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  5. 深入浅出Redis-redis哨兵集群

    1.Sentinel 哨兵 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所 ...

  6. [原]Redis主从复制各种环境下测试

    Redis 主从复制各种环境下测试 测试环境: Linux ubuntu 3.11.0-12-generic 2GB Mem 1 core of Intel(R) Core(TM) i5-3470 C ...

  7. Redis 简单搭建

    ======== redis ======== 1. redis setup and test : 1. download the package from https://redis.io/down ...

  8. Redis主从复制

    大家可以先看这篇文章ASP.NET Redis 开发对Redis有个初步的了解 Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此 ...

  9. redis的安装配置

    主要讲下redis的安装配置,以及以服务的方式启动redis 1.下载最新版本的redis-3.0.7  到http://redis.io/download中下载最新版的redis-3.0.7 下载后 ...

随机推荐

  1. FIBON高精度

    #include<stdio.h> #include<string.h> int u,n; ],b[],h[]; ],y[],z[]; int main() { char s( ...

  2. H5新特性:

    新增选择器 document.querySelector.document.querySelectorAll 拖拽释放(Drag and drop) API 媒体播放的 video 和 audio 本 ...

  3. Mysql闪回工具之binlog2sql的原理及其使用

    生产上误删数据.误改数据的现象也是时常发生的现象,作为运维这时候就需要出来补锅了,最开始的做法是恢复备份,然后从中找到需要的数据再进行修复,但是这个时间太长了,对于大表少数数据的修复来讲,动作太大,成 ...

  4. SSIS 通过 WINscp 从SFTP下载文件

    1.通过SSIS的process task调用 winscp :C:\Program Files (x86)\WinSCP\WinSCP.exe /script="C:\SFTPFile\T ...

  5. Velocity模板语法说明

    Velocity基本语法 "#"用来标识Velocity的关键字,包括#set.#if .#else.#end.#foreach.#end.#include.#parse.#mac ...

  6. PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20)

    PAT (Basic Level) Practise (中文)-1033. 旧键盘打字(20)  http://www.patest.cn/contests/pat-b-practise/1033 旧 ...

  7. PLAYGROUND 可视化

    PLAYGROUND 可视化 由 王巍 (@ONEVCAT) 发布于 2015/09/23 在程序界,很多小伙伴都会对研究排序算法情有独钟,并且试图将排序执行的过程可视化,以便让大家更清晰直观地了解算 ...

  8. 【OS_Linux】Linux中虚拟机的三种上网方式——桥接、NAT、Host-only

    1.桥接 桥接方便做实验,配置ip方便.可以和局域网中的其他机器进行通信,也可以和公网进行通信.缺点是会占用主机所在局域网的一个ip. 2. NAT NAT模式下虚拟机可以和主机进行通信,可以上网,而 ...

  9. Qtopia移植

    Qtopia 是Trolltech 公司为采用嵌入式Linux操作系统的消费电子设备而开发的综合应用平台, Qtopia包含完整的应用层.灵活的用户界面.窗口操作系统.应用程序启动程序以及开发框架.下 ...

  10. PAT Basic 1060

    1060 爱丁顿数 英国天文学家爱丁顿很喜欢骑车.据说他为了炫耀自己的骑车功力,还定义了一个“爱丁顿数” E ,即满足有 E 天骑车超过 E 英里的最大整数 E.据说爱丁顿自己的 E 等于87. 现给 ...