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 * 从服务器断线重连所需平均时间(秒) * 主服务器每秒产生的写命令数量
SLAVEOF以后的更多相关文章
- windows下Redis主从复制配置(报错:Invalid argument during startup: unknown conf file parameter : slaveof)
主从复制配置中的遇到的异常: Invalid argument during startup: unknown conf file parameter : slaveof 把Redis文件夹复制两份 ...
- Redis的 SLAVEOF 命令
SLAVEOF host port SLAVEOF 命令用于在 Redis 运行时动态地修改复制(replication)功能的行为. 通过执行 SLAVEOF host port 命令,可以将当前服 ...
- windows环境redis主从安装部署
准备工作 下载windows环境redis,我下载的是2.4.5,解压,拷贝一主(master)两从(slaveof).主机端口使用6379,两从的端口分别为6380和6381, 我本地索性用6379 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 深入浅出Redis-redis哨兵集群
1.Sentinel 哨兵 Sentinel(哨兵)是Redis 的高可用性解决方案:由一个或多个Sentinel 实例 组成的Sentinel 系统可以监视任意多个主服务器,以及这些主服务器属下的所 ...
- [原]Redis主从复制各种环境下测试
Redis 主从复制各种环境下测试 测试环境: Linux ubuntu 3.11.0-12-generic 2GB Mem 1 core of Intel(R) Core(TM) i5-3470 C ...
- Redis 简单搭建
======== redis ======== 1. redis setup and test : 1. download the package from https://redis.io/down ...
- Redis主从复制
大家可以先看这篇文章ASP.NET Redis 开发对Redis有个初步的了解 Redis的主从复制功能非常强大,一个master可以拥有多个slave,而一个slave又可以拥有多个slave,如此 ...
- redis的安装配置
主要讲下redis的安装配置,以及以服务的方式启动redis 1.下载最新版本的redis-3.0.7 到http://redis.io/download中下载最新版的redis-3.0.7 下载后 ...
随机推荐
- ERROR 2059 (HY000): Authentication plugin 'caching_sha2_password' cannot be loaded: /usr/lib64/mysql/plugin/caching_sha2_password.so: cannot open shared object file: No such file or directory
部署docker下的mysql时出现以下报错 [root@docker ~]# mysql -h192.168.30.22 -uroot -p Enter password: 出现报错: ERROR ...
- 自己开发一个APP需要多少钱
广州APP开发公司[启汇网络]经常遇到有开发定制APP软件需求的企业,通常第一句问的就是“开发一款APP需要多少钱”,在做完客户行业的市场调查后,再了解客... 广州APP开发公司[启汇网络]经常遇到 ...
- 实现类似AOP的封装和配置
这是张孝祥老师Java进阶讲解中最后一个视频,就是实现类似spring中的AOP的封装和配置,特别特别小型的一个框架雏形,但是spring中的核心思想还是体现出来了,真的厉害,张老师!!! 一.重点知 ...
- Windows平台下使用vs code搭建python3环境(1)
前言:最近几周在使用python开发的过程中,碰到了好多坑,由于以前使用visual studio 2015习惯了,导致刚开始搭建python开发环境以及管理各种包的时候有点不习惯,再加上python ...
- 【OS_Linux】Linux 基本命令整理
1. 查看目录文件:ls2. 打印当前工作目录:pwd3. 查看文件内容:cat 文件名4. 打开编辑器:vim 文件名 1 2 3 4 5 修改:按Insert键 退出修改模式:按Esc 键 进入输 ...
- java代码解析二维码
java代码解析二维码一般步骤 本文采用的是google的zxing技术进行解析二维码技术,解析二维码的一般步骤如下: 一.下载zxing-core的jar包: 二.创建一个BufferedImage ...
- Silverlight客户端加载DWG图纸方案
前段时间一直再研究怎么才能在Silverlight客户端加载 DWG图纸,ArcGIS API For Silverlight中可以加载Shp文件,但是不能加载DWG,最后想出了一个方法步骤如下: 1 ...
- 大数据学习——hbase的shell客户端基本使用
1 基本shell命令 1 在hbase的 bin目录下进入命令行 ./hbase shell 2 查看有哪些表 list 3 创建一个表 create 't_user_info', {NAME = ...
- centos 7 安装vmware 12
1.下载VMware 衔接地址 http://www.vmware.com/products/workstation/workstation-evaluation ,下载Linux版本的VMware. ...
- 2017 ACM/ICPC Asia Regional Shenyang Online
cable cable cable Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...