为了提供整个缓存的可用性,可以给主服务器添加备用服务器,即从服务器。通过SLAVEOF命令把当前服务器设置成某台服务器的从服务器。
老版本同步过程
旧版本(2.8之前)主从服务器数据同步过程如下:
为了解决2.8之前版本SYNC命令的性能问题,2.8版本设计了一个新的命令PSYNC,PSYNC命令分为完整重同步和部分重同步,完整重同步过程用于从服务器初始化时初次复制的情况和SYNC命令基本一致,PSYNC则用于断线后重新复制,在条件允许的情况下,它不会生成RDB文件,而是给从服务器回复一个+Continue表示执行部分重同步,并且把从服务器断线后主服务器执行的修改数据库的命令发送到从服务器,从服务器执行这些命令同步数据库。
部分重同步功能由下面几个部分构成:
主服务器的复制偏移量和从服务器的复制偏移量:当主服务器在向从服务器进行命令同步时,主服务器和从服务器会各自记录一个复制偏移量,当主从服务器的数据库状态一致时这两个复制偏移量是相同的,如果这两个偏移量不一致说明当前主从服务器的状态不一致。主服务器的复制积压缓冲区:复制积压缓冲区是一个固定大小的FIFO队列,当队列已满时会弹出最早插入的数据,在主服务器进行命令传播时会同时把命令放到缓冲区中,缓冲区包含两部分数据,偏移量和字节。在进行复制时从服务器会将偏移量上报到主服务器,主服务检查当前偏移量是否还存在缓冲区中,如果存在进行部分重同步,如果不存在进行完整重同步。因为这个积压缓冲区是一个固定大小的队列,所以当从服务器长时间断线时,从服务器的复制偏移量很可能已不再缓冲区中,这时候只能进行完整重同步。服务器的运行ID:初次同步时主服务器会把ID发给从服务器,从服务器保存主服务器ID,当断线重连后,会把之前保存的主服务器ID上报给主服务器,主服务器检查从服务器之前复制的主服务器ID是否和自己的ID相同,如果相同,执行部分重同步,如果不同说明从服务器之前记录的状态不是当前主服务器,这时候需要执行完整重同步。
PSYNC命令实现
初始复制或者之前执行过SLAVEOF no one命令,执行完整重同步:发送PSYNC ? -1命令到主服务器。如果从服务器已经复制过某个主服务器,在开始新复制时向主服务器发送PSYNC
回复+FULLRESYNC
新版本同步过程
2.8及以后版本复制过程:设置主服务器地址和端口,通过调用SAVEOF
心跳检测
在命令传播阶段,从服务器默认每秒一次的频率向主服务器发送命令:REPLCONF ACK检测从服务器的网络连接状态,检测主从服务器连接是否正常,如果主服务器超过一定时间没有收到从服务器的REPLCONF ACK 命令,那么它们的连接可能出了问题。辅助实现min-slaves选项,min-slaves-to-write和min-slaves-max-lag两个选项可以防止主服务器在不安全的情况下执行写命令,min-slaves-to-write 3 min-slaves-max-lag 10 表示如果从服务器少于3个,或者3个从服务器的延迟都大于10秒时,主服务器拒绝写命令。检测命令丢失,主服务器接收到从服务器的REPLCONF ACK 命令之后会检查从服务器的偏移量是否和主服务器的一致,如果不一致会把积压缓冲区中的从服务器偏移量后面的命令发送到从服务器。