主从复制是指用户能够搭建多个服务器,其中几个服务器当作主服务器,提供写功能。其他的服务器当作从服务器,提供读功能。每当主服务器收到写请求时,同时须要把数据发送给从服务器。保证主从服务器的数据保持最终一致性。利用这个机制,能够利用廉价的服务器搭建高可用,高并发集群。主从复制是搭建高可用集群的必备利器。java
在Redis中可使用slaveof命令让一个Redis实例去复制另外一个Redis实例的内容。这里须要注意当A实例执行该命令去复制B实例的内容后,之前A实例的内容都将被B实例的内容覆盖。同时在从服务器将被设置为只读,向从服务器发送写命令时,将被拒绝。(也能够在redis.conf中配置该命令,启动时就发起主从同步)redis
当从服务器发起slaveof命令后,主从服务器之间经过TCP长链接进行通讯,主要是如下步骤:缓存
第一次完整的主从同步就完成了。而后主从之间会维持TCP链接,每次master收到新的写命令后,都会发给从服务器。服务器
若是期间链接断了,当从服务器从新连上主服务器后,上述的步骤会从新来一遍。能够发现这是很低效的,由于主服务器只须要把断连期间的写入命令发给从服务器就能够了,不须要从新生成RDB文件。(生成RDB文件是一个耗时操做,设计磁盘的读写)。网络
注意:从服务器在加载RDB文件过程当中是阻塞的,没法处理客户端的请求。并发
基于上述缘由(特别是断线时间特别短时),Redis推出了新的同步命令psync。高并发
psync将同步过程分为了两块:一、完整同步;二、部分同步。spa
完整同步也叫初次同步,也就是第一次主从同步。步骤跟v1上述是一致的。设计
部分同步主要用户断线重连后的同步,它能够将断线期间的写入命令发送给从服务器,而不须要整个RDB文件,极大的节约了资源。当从服务器从新链接了主服务器后,会发送psync命令,而后主服务器回复continue命名,而且发送缺乏的写入命令到从服务器。code
redis完成部分同步功能主要依赖于如下部分:
一、主服务器的复制偏移量
二、从服务器的复制偏移量
三、命令缓存区(FIFO队列,默认大小1MB)
四、服务器运行Id
每次主服务器向从服务器传递N个字节命令后,就在把本身的偏移量+N。从服务器同理。同时主服务器还会将命令写入到命令缓存区里。当从服务器重连是发生以下步骤:
每一个Redis都有本身的惟一标识Id。在启动时自动生成,由40个随机的十六进制字符组成。当发送第一次主从同步时,master会将本身的id发送会从服务器,从服务器会将其保存起来。断线重连时,从服务器请求同步时还会将这个id发送给主服务器,主服务器判断该id与本身的id是否一致,若是一致则继续执行部分同步的剩余步骤。不然执行完整同步。
主从服务器创建链接后,默认每隔1秒,从服务器会想主服务器发送REPLCONF_ACK <offset>
报告本身的状态。
主服务器能够从这个命令中检测出几个问题:
一、主从之间的网络链接状态
若是主服务器在规则时间内没有收到从服务器的心跳命令,就能够认为主从之间出现了问题。这个时候若是配置了
```java
复制代码
min-slaves-to-write 3 min-slaves-max-lag 10
//若是从服务器数小于3或者3个服务器的心跳检测延迟值都大于等于10秒,主服务器将拒绝写命令 ```
二、检测新的写命令是否丢失
每次主服务器收到从服务器心跳命令里的offset时,都会与本身的offset进行比较,若是小于本身的。那么能够知道某次传递的写命令在网络上丢失或者从服务器加载失败,这个时候主服务器会主动将这部分缺乏的命令发送给从服务器(须要缺失命令还在缓存区,若是不在猜想应该是发起一次完整同步,未验证过)。
三、辅助实现min-slaves
主从服务器创建套接字链接后,从服务器首先会发起Ping命令检测套接字的读写是否正常。收到主服务器的Pong命令后证实正常。而后在判断主服务器是否须要身份认证,发起密码。而后进行复制流程。