主从复制简介
定义:
主从复制指的是一个redis服务器数据,复制到其他的Rdis服务器,前者称为主节点,后者
成为从节点,数据的复制单向的,只能从主节点到从节点,Master以写为主,Slave以读为主。
默认情况下,每台Redis服务器都为主节点,且·一个主节点可以有多个从节点,但一个从节点只能有一个主节点。
主从复制的主要包括:
1.数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2.故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障修复,实际上是一种服务冗余。
3.负载均衡:在主从复制的基础上,配合读写分离,可以有主节点提供写服务,由从节点提供读服务,分担服务器的均衡,尤其是读多写少的情况下,大大提高Redis的并发量。
4.高可用基石:除了上述作用外,主从复制还是哨兵和集群能够实现的的基础,因此说Redis是高可用基础。
第一次同步
redis命令实现主从服务器
我们可以使用replicaof(Reids5.0之前使用slaveof)命令形成主服务器和从服务器的关系。
例如:
#服务器B执行以下命令
replicaof 服务器A的ip地址 服务器A的Redis的端口号
执行完成后服务器B成为了服务器A的从服务器,然后与服务器·进行第一次同步。
第一次同步的三个阶段
主从服务器的第一次同步可以分为三个阶段:
1.建立连接,协商同步
- 执行replicaof命令后,从服务器就会给主服务器发送psync命令表示要进行数据同步。
psync命令包含两个参数,分别是主服务器的runID和复制进度的offset.
runID:每台redis服务器在启动时都会产生一个随机ID来为一标识自己。当从服务器和·主服务器第一次进行同步时,因为不知道主服务器的ID,所以将其设置为?。
offset:复制进度,第一次同步时,其值为-1.
- 主服务器收到psync后,会用FULLRESYNC作为响应命令返回给对方。并且相应命令会带上
这两个参数返回给从服务器。FULLRESYNC响应命令的意图是采用全量复制的方式。
所以第一阶段的主要作用就是建立连接,为全量复制做准备。
2.主服务器同步数据给从服务器
- 接着主服务器会执行bgsave命令来生成RDB文件,然后把文件发送给从服务器。从服务器收
到RDB文件后,会清空当前的数据,然后载入RDB文件。
注意:这里生成的RDB主进程并不会阻塞,因为bgsave命令生成一个子进程来完成生成RDB文件的工作,是异步工作。
但是写操作命令并没有记录到刚刚生成的RDB文件中,这是主从服务器的数据就不一致了,为了
保证主从服务器的数据保持一致,主服务器将一下三个时间的写操作命令写入到replication buffer缓冲区:
1.主服务器生成的RDB文件期间
2.主服务器发送RDB文件期间
3.从服务器加载RDB文件期间
3.主服务器发送写操作命令给从服务器
第二阶段并没有处理replication buffer缓冲区的写操作内容,这是第三阶段的·主要工作。
在主服务器生成的 RDB 文件发送完,从服务器收到 RDB 文件后,丢弃所有旧数据,将 RDB 数
据载入到内存。完成 RDB 的载入后,会回复一个确认消息给主服务器。
接着,主服务器将 replication buffer 缓冲区里所记录的写操作命令发送给从服务器,从服务器执
行来自主服务器 replication buffer 缓冲区里发来的命令,这时主从服务器的数据就一致了。
至此,主从服务器的第一次同步的工作就完成了。
总结:
第一阶段:建立连接,协商同步
第二阶段:主服务器同步数据给从服务器
第三阶段:主服务器发送新写操作命令给从服务器

命令传播
主从服务器完成第一次同步后就会维护一个TCP连接。

后续服务器可以通过这个连接将写操作命令传送给从服务器,然后从服务器执行哦那个该命令。
注意:该连接为长连接,目的是避免频繁的TCP连接和断开带来的性能和开销。
增量复制
主服务器在完成第一次同步后,就会基于长连接进行命令传播。可是当网络延时或者断开,主从服务器的数据就没办法和主服务器保持一致,客户端就可能从主服务器读到旧数据。
引入问题:断开的网络又恢复正常了,怎么继续保持主从服务器的数据一致。
在redis2.8之前,主从服务器会进行全量复制,redis2.8之后采用增量复制,也就是只会把网络断开期间主服务器接收到的写操作命令,同步给服务器。
主服务器有以下三个步骤:
从服务器在恢复网络后,会发送psync命令给主服务器,此时psync命令里offset参数不是-1;
主服务器收到该命令,然后发送CONTINUE响应命令告诉从服务器采用增量复制的方式让同步数据。
然后主服务器将断线期间,所有执行的命令发送给从服务器,然后从服务器执行这些命令。
注意:那么主服务器怎么知道将那些数据增量复制给从服务器
repl_backlog_buffer:是一个环形缓冲区,用于主从服务器断连后,从中找到差异
rellication offset:标记上面环形缓冲区的同步进度,主从服务器都有各自的偏移量主服务器使
用master_repl_offset 来记录自己「写」到的位置,从服务器使用 slave_repl_offset 来记录自己
读」到的位置。
注意:repl_backlog_buffer缓冲区什么时候写入呢?
在主服务器进行命令传播时,不仅会把写命令发送给从服务器,还会将写命令写入repl_backlog_buffer缓冲区里,因此这个缓冲区里会保存最近的传播的写命令。
网络断开后,当从服务器重新连接上主服务器,从服务器会通过psync命令将自己的复制偏移量slave_repl_offset发送给主服务器,主服务器根据自己的master_repl_offset和slave_repl_offset之间的差距,决定对从服务器执行那种同步操作:
如果判断出差距在缓冲区里,主服务器采用增量同步。
否则采用全量复制的同步数据。

repl_backlog_buffer的缓冲区大小为1MB,他是一个环形缓冲区,当缓冲区满时,主服务器继续写入时,就会覆盖之前写入的数据。
总结
主从复制的实现主要有三种模式:全量复制,基于长连接的命令传播,增量复制。
建立主从服务器时:主从服务器建立连接,主服务器发送RDB文件,服务器接收后,主服务器将repliucation缓冲区数据发送,后将维持TCP连接,进行长连接的命令传播,后如果网络延迟,断开连接则选择是全量复制还是增量复制。