一、旧版复制
redis复制功能分为同步(sync)和命令传播(command propagate)两个操作
同步:
将从服务器的数据库状态更新至主服务器所处的数据库状态
slaveof命令后,从服务器首先执行同步操作,从服务器需要向主服务器发送sync命令来实现。主服务器收到sync命令,主服务器执行bgsave命令,后台生成一个rdb文件,并使用一个缓冲区记录从现在开始执行的所有命令,当bgsave执行完毕,主服务器会将RDB文件发送给从服务器,从服务器接收并载入这个RDB文件,主服务器将记录在缓冲区里面的所有写命令发送给从服务器,从服务器执行这些命令,将自己的数据库状态更新至主服务器当前的状态。
命令传播:
主从数据库状态出现不一致,让主从数据库状态回到一致状态同步
缺陷:
复制两种情况:1初次复制(之前没有复制过,或者复制不同的主服务器)2断线后重复制(效率低)
SYNC命令非常好资源,BGSAVE命令会耗费大量CPU、内存、磁盘IO,发送RDB文件耗费大量网络资源,并对主服务器响应命令请求的时间产生影响,从服务器在载入RDB文件期间,从服务器会因为阻塞而没办法处理命令请求。
二、新版复制功能(2.8开始)
使用PSYNC命令代替SYNC命令
psync命令具有完整重同步和部分重同步两种模式:
完整重同步:和旧版复制一样
部分重同步则用于处理断线后的重复制情况。当从服务器在断线后重新连接主服务器,如果条件允许,主服务器可以将主从服务器连接断开期间执行的写命令发送给从服务器,从服务器只需要执行这些命令即可。
三、部分重同步实现
分为3个部分来实现部分重同步:
主服务器的复制偏移量和从服务器的复制偏移量
主服务器的复制积压缓冲区
服务器的运行ID
1、复制偏移量:
主服务每次向从服务器传播n个字节的数据时,就将自己的复制偏移量的值加N
从服务器每次收到主服务器传播来的n个字节的数据时,就将自己的复制偏移量加N
2、复制积压缓冲区:
复制积压缓冲区是由主服务器维护的一个固定长度先进先出队列。当主服务器进行命令传播时,会把命令发送给从服务器和复制积压缓冲区里,且复制积压缓冲区会为队列中的每个字节记录响应的复制偏移量。
从服务器的复制偏移量依旧存在于复制积压缓冲区中,则使用部分同步实现复制。
3、服务器的运行id
主服务器将自己的id发送给从服务器,从服务器断线重连时,会向当前连接的主服务器发送之前保存的id
四、复制的实现
- 客户端向从服务器发送slaveof 127.0.0.1 6379命令
- 地址和端口保存在从服务器将masterhost和masterport属性里面,然后返回ok
- 从服务器根据刚设置的属性,创建连向主服务器的套接字连接,如果连接到主服务器,从服务器为这个套接字关联一个专门用户处理复制工作的文件时间处理器,比如接受rdb文件或写命令。主服务器接收到从服务器的套接字连接后,会为其创建相应的客户端状态。(从服务器是主服务器的客户端)
- 从服务器向主服务器发送ping命令,检测套接字的读写状态是否正常,检测主服务器能否正常处理命令请求。
- 身份验证(相关参数:masterauth requirepass)
- 从服务器向主服务器发送自己的监听端口号
- 同步,主服务器成为从服务器的客户端,向从服务器发送写命令
- 命令传播
[20084] 27 Aug 14:15:10.151 * SLAVE OF 127.0.0.1:6379 enabled (user request from 'id=3 addr=127.0.0.1:59036 fd=8 name= age=76 idle=0 flags=N db=0 sub=0 psub=0 m ulti=-1 qbuf=0 qbuf-free=32768 obl=0 oll=0 omem=0 events=r cmd=slaveof') [20084] 27 Aug 14:15:10.760 * Connecting to MASTER 127.0.0.1:6379 [20084] 27 Aug 14:15:10.761 * MASTER <-> SLAVE sync started [20084] 27 Aug 14:15:10.762 * Non blocking connect for SYNC fired the event. [20084] 27 Aug 14:15:10.764 * Master replied to PING, replication can continue.. . [20084] 27 Aug 14:15:10.769 * Partial resynchronization not possible (no cached master) [20084] 27 Aug 14:15:10.800 * Full resync from master: 0eaba21261b9ba4a9f9694f54 366aee8069d6cb5:1 [20084] 27 Aug 14:15:10.941 * MASTER <-> SLAVE sync: receiving 715161 bytes from master [20084] 27 Aug 14:15:10.955 * MASTER <-> SLAVE sync: Flushing old data [20084] 27 Aug 14:15:10.956 * MASTER <-> SLAVE sync: Loading DB in memory [20084] 27 Aug 14:15:10.964 * MASTER <-> SLAVE sync: Finished with success
五、心跳检测
从服务器每秒一次地向主服务器发送命令:replconf ack <offset>
作用:检测主从服务器连接状态,辅助min-slaves配置选项,检测命令丢失