主服务器叫master,从服务器叫slave,主人与奴隶。为了使得主从服务器状态一致,需要进行复制。
1.旧版复制
从服务器向主服务器发送SYNC命令,请求复制,则主服务器执行BGSAVE生成一个RDB文件,并用一个缓冲区记录现在开始的写命令,BGSAVE命令完成后,先让从服务器载入RDB文件,再把缓冲区里的命令发给从服务器,让其同步。
2.命令传播
主从服务器通过 同步 状态一致后,当主服务器执行写命令时,顺便发给它的所有从服务器去执行,使得主从保持一致。
3.初次复制和断线后复制
- 初次复制使用旧版复制
- 断线后复制可能就执行了几条写命令,用旧版复制太浪费资源和时间
4.新版复制(2.8版本开始)
PSYN命令,有两种重同步方法,完整重同步和旧版复制SYNC命令一样
部分重同步用于处理断线后复制,将断线期间主服务器执行的写命令发送给从服务器,具体实现如下:
(1)主从服务器分别维护一个复制偏移量
主服务器每次向从服务器传播N个字节数据时,就将自己的复制偏移量+N;从服务器收到N个字节数据,就将自己的复制偏移量+N。断线后从服务器通过发送偏移量给主服务器以获取 需要达到同步状态的写命令。
(2)复制积压缓冲区
主服务器维护一个默认1MB的队列,保存发送给从服务器的命令,队头持续弹出,队尾持续压入。根据需要调整复制积压缓冲区大小,一般为( 2 * 断线秒数 * 主服务器平均每秒产生的写数据量 )。
(3)运行ID
运行ID由40个随机的十六进制字符组成,从服务器会保存主服务器的运行ID,断线后再连如果目标服务器的ID和记录的一样就用部分重同步,否则执行完整重同步。
5.复制的完整流程
从服务器想复制主服务器
(1)从服务器属性里 设置主服务器的地址和端口
char* masterhost;
int masterport;
(2)建立套接字连接
(3)从服务器发送PING命令。检查套接字的读写状态是否正常 以及 主服务器能否正常处理请求,不正常就断开并重新创建连向主服务器的套接字。
(4)身份验证
(5)从服务器向主服务器发送监听端口,让主服务器添加以监听
(6)从服务器发送PSYNC命令执行同步操作,主从互为客户端
(7)命令传播
6.心跳检测
一秒一次,检测网络连接状态,辅助实现min-slaves(防止主服务器在不安全的情况下执行写命令),检测命令丢失。
参考&引用
《redis设计与实现》