redis复制的原理
如何使用
slaveof命令
被复制的服务器叫做主服务器,复制的服务器叫做从服务器,A > SLAVEOF B,A就成了B的从服务器。1
127.0.0.1:3325 > slaveof 127.0.0.1:6430
旧版复制介绍以及缺陷
Redis的复制功能分为同步和命令传播,同步用于将从服务器所属的数据库状态更新为从服务器所属的数据库状态,命令传播作用于主服务器,从服务器拿到脏数据,主服务器通过这种方式维持数据一致性
1. 同步的过程
- 从向主发送SYNC命令
- 主接收SYNC命令并执行BGSAVE,同时在后台生成一个RDB文件并开启一个缓冲区记录从现在开始执行的所有写命令
- 主执行完BGSAVE后得到一个RDB,将这个RDB发送给从服务器,从服务器执行RDB
- 主将缓冲区命令发送至从,从执行这些命令。

2. 命令传播
主服务器中数据出现了更改,需要保持数据的一致性,于是向从服务器发送命令达到相同的效果。
3. 旧版复制的缺陷
初次复制没有问题,问题出现在主服务器断线重连后出现的问题。注意问题描述:问题出在,旧版本的复制下,在出现断线后又上线的情况中,从服务器为了接收断线期间新的命令,会再发起一次SYNC,此时主服务器会再次将之前所有的命令同步到从,但是从实际上需要的只是断线期间没有接收到的那部分数据,这里造成了极大的资源浪费。因为SYNC是非常耗资源的。
新版复制所做的改进
- 新版复制用PSYNC代替SYNC,PSYNC有完整重同步和部分重同步两种模式
- 完整重同步和旧版的同步一样
- 部分重同步用于解决旧版复制的缺陷。
部分重同步过程
部分重同步在重连后就会将断线期间新生成的命令发给从服务器
部分重同步的实现
三个概念:主从服务器的复制偏移量、复制积压缓冲区、服务器的运行ID
复制偏移量
主从各有一个, 复制多少,双方的复制偏移量移动多少。
复制积压缓冲区
对于断线重连的情况,使用一个固定大小的复制积压缓冲区存储断线期间的写命令,如果说从服务器偏移量之后的命令还存在复制积压缓冲区里面,就使用部分重同步。否则使用完整重同步。
服务器运行ID
一台服务器的唯一标识
新版本复制PSYNC执行过程

复制的原理
redis服务器之间的复制实际上就是做了一次基于socket套接字的通信过程,具体步骤如下:
- 从服务器向主服务器发送slave of命令
- 主服务器返回OK后从服务器为此次连接建立套接字,从服务器会专门开启一个线程来接收主服务器传过来的文件和命令。
- 建立套接字连接后,从服务器会向主服务器发送ping命令检查联通状态,主服务器返回pong命令表示连接成功,可以开始复制。超时或者返回ERR都视为建立失败。
为什么建立完套接字还要发一个ping命令,作用1.检查套接字读写状态。作用2.检查主服务器状态是否异常。
- 身份验证。如图

- 发送端口信息,这个部分主服务会监听从服务器的端口,进行命令传播和同步
补充
对于redis复制,还有几点需要补充的是
- 心跳检测是从服务器向主服务器发送命令,每秒一次
- 心跳检测可以检测网络状态
- 心跳检测可以检测命令是否丢失,原理是通过从服务器发过来的偏移量的值看双方的复制偏移量是否一致,不一致说明有命令丢失的情况。
- 心跳检测命令是REPLCONF ACK <副本偏移量>