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 下载后 ...
随机推荐
- 兼容IE6\7\8浏览器的html5标签的几个方案
html5大行其道的时代已经到来.如果你还在等待浏览器兼容,说明你已经与web脱节几条街了.当然,这得益于移动客户端的蓬勃发展.如果还在纠结于,是否应该掌握html5和css3技术时,请狠狠的抽自己几 ...
- caffe layer层cpp、cu调试经验和相互关系
对于layer层的cpp文件,你可以用LOG和printf.cout进行调试,cu文件不能使用LOG,可以使用cout,printf. 对于softmaxloss的layer层,既有cpp文件又有cu ...
- 数据库_6_SQL基本操作——库操作
SQL基本操作——库操作:对数据库的增删改查 一.新增数据库(创建) 基本语法:create database 数据库名字 [库选项]: 库选项用来约束数据库,分为两个选项:1.字符集设定:chars ...
- cmake 指定输出目录
$ mkdir ~/cpp-netlib-build $ cd ~/cpp-netlib-build $ cmake -DCMAKE_BUILD_TYPE=Debug \ > -DCMAKE_C ...
- PAT (Basic Level) Practise (中文)-1025. 反转链表 (25)
PAT (Basic Level) Practise (中文)-1025. 反转链表 (25) http://www.patest.cn/contests/pat-b-practise/1025 ...
- ios之自定义导航栏上的返回按钮
导航栏的按钮,右边的按钮是可以自己随意添加的.但左边的返回按钮怎么定制?你会说,添加一个自己的按钮呗!你可以试试看,这样行不行. 正确的答案是重载UINavigationController类的pus ...
- [LUOGU] P2196 挖地雷
题目背景 NOIp1996提高组第三题 题目描述 在一个地图上有N个地窖(N<=20),每个地窖中埋有一定数量的地雷.同时,给出地窖之间的连接路径.当地窖及其连接的数据给出之后,某人可以从任一处 ...
- [LUOGU] 1892 团伙
题目描述 1920年的芝加哥,出现了一群强盗.如果两个强盗遇上了,那么他们要么是朋友,要么是敌人.而且有一点是肯定的,就是: 我朋友的朋友是我的朋友: 我敌人的敌人也是我的朋友. 两个强盗是同一团伙的 ...
- MySQL 资料库概论与MySQL 安装
本文来自:https://www.breakyizhan.com/sql/5648.html 1. 储存与管理资料 储存与管理资料一直是资讯应用上最基本.也是最常见的技术.在还没有使用电脑来管理你的资 ...
- LeetCode(39) Combination Sum
题目 Given a set of candidate numbers (C) and a target number (T), find all unique combinations in C w ...