如果支持业务服务的Redis只有一台的话,就很危险。当单机Redis出现问题的时候,就会导致服务不可用。
要避免出现这种单点故障,最好的方法就是备份到其他服务器上,让这些服务器也可以对外提供业务服务,这样子就算单机服务器出现了问题,其他服务器也可以继续对外提供服务
如果的多台服务器的进行提供服务的话,就会有新的问题出现,也就是数据的一致性
这些服务器之间的数据如何保证一致性呢?数据的读写操作是否每台服务器都可以处理呢?
Redis提供了主从复制模式,来避免上述的问题
那就让我们一起来了解一下Redis的主从复制吧
第一次同步
首先我们得先确定一个主服务器吧,或者说来确定谁是从服务器吧
在Redis中我们可以在从服务器上使用下面的命令来绑定主服务器,有点认大哥的味道
replicaof <主服务的ip> <主服务器的redis端口号>当我们执行完认大哥的命令后
主从服务器之间就会进行第一次同步的操作,改操作分为三个步骤
- 
建立链接、协商同步 
- 
主服务器同步数据到从服务器 
- 
主服务器发送新写操作命令给从服务器 
第一阶段 建立链接、协商同步
执行了前面的命令后,从服务器会向主服务器发送psync命令,表示要同步数据
在psync命令中,包含了主武器的runID和复制进程offset
当主服务器收到psync命令后,会用FULLPESYNC作为响应命令返回给对方
并且在这个响应命令会带上两个参数,一个是主服务器的runID和主服务器目前的复制进度offset
要注意的FULLPESYNC响应命令的意图是采用全量复制的方式,也就是说主服务器会把所有的数据都同步给从服务器
所以说,第一阶段是为了全量复制做准备
第二阶段 主服务器同步数据到从服务器
第一阶段后,主服务器会执行bgsave生成RDB文件,随后将RDB文件发送给从服务器
从服务器接收后,先将自己的服务器上的数据都清空,然后载入RDB文件
这样子就使得主服务器和从服务器的数据一致了
但是要注意一点的是,我们无法保证在主服务器生成RDB文件的时候,以及从服务器在加载RDB的期间,没有新的写操作到主服务器上
那么为了保证主从服务器的数据一致性,主服务器在下面三个时间间隙中将收到的写操作命令,写入到replication buffer缓冲池中:
- 
主服务器生成RDB文件期间 
- 
主服务器发送RDB文件给从服务器期间 
- 
从服务器加载RDB文件期间 
第三阶段 主服务器发送新写操作命令给从服务器
在第二阶段后,从服务器将RDB文件写入后,从服务器会向主服务器发送一个确认命令。
而后主服务器会将replication buffer缓冲区中的写操作发送给从服务器,从服务器执行后,这时主从服务器的数据就一致了
到这里,第一次同步工作就做完了
命令传播的方式-长连接的命令传播
当主从服务器完成了第一次同步后,主从服务器会建立一个TCP链接并且维护
后续主服务器就可以通过这个链接继续将写操作命令传播给从服务器,使得主从服务器的数据库状态相同
这个长连接是为了避免频繁的TCP链接和断开带来的性能开销
上面的这个过程被称为基于长连接的命令传播,通过这种方式来保证第一次同步后的主从服务器的数据一致性
分摊主服务器的压力
前面我们知道了主从服务器的第一次同步中,主服务器会做两件耗时的操作,生成RDB文件和传输RDB文件
如果从服务器很多的话,会给主服务器带来不小的压力
就好比一个公司 在刚刚起步的时候,老板直接管理还行。但是如果员工越来越多,老板就会忙不过来,这个时候就会提拔一些员工当管理人员,去管理部分的员工,老板直接和管理的员工对接就好了
Redis也是一样,从服务器可以有自己的从服务器。它不仅可以接收主服务器的同步数据,自己也可以同时作为主服务器的形式将数据同步给从服务器
这样子原先都在主服务器的生成RDB和传输RDB的压力可以分摊到其他某些从服务器上
增量复制
我们知道当主从服务器完成第一次同步后, 就会基于长连接进行命令传播。
但是网络这个东西,有时候说断就断,有时候莫名其妙的延迟都是正常的
但是我们要注意的是,如果网络出现了波动或者断开,这个时候从服务器就没办法和主服务器保持一致了,客户端就可能从从服务器读到旧数据了
所以当网络恢复了,又要怎么继续保证主从服务器的一致性呢
在Redis2.8之前如果要继续保证的话,就会立马进行一次全量复制,当然这样子开销太大了。完全没必要
所以在Redis2.8后,主从服务器会采用增量复制的方式继续同步,也就是只将在网络断开期间主服务器接收到的写操作的命令同步给从服务器
主要有三个步骤
- 
从服务器网络恢复后,发送psync命令给主服务器 
- 
主服务器接收命令后,用CONTINUE命令告诉从服务器接下来采用增量复制的方式同步数据 
- 
然后主服务将主从服务器断线期间,所执行的写命令发送给从服务器,然后从服务器执行这些命令 
那么主服务器是怎么知道要将哪些增量数据发送给从服务器呢?
答案就在
- 
repl_backlog_buffer 一个环形缓冲区,用于主从服务器断连后,从中找到差异数据 
- 
replication offset 标记上面缓冲区的同步进度 主从服务器都有各自的偏移量 主服务器用master_repl_offset 来记录自己写到的位置 从服务器使用 slave_repl_offset 来记录自己读到的位置 
在repl_backlog_buffer缓冲区 主要是将主服务器进行命令传播时,会将传播的写命令记录到缓冲区中,当网络恢复正常后,从服务器会在请求中携带自己的偏移量 如果偏移量还在缓冲区中 则进行增量复制 否则就是全量同步的方式了