全量复制过程
1、从节点发送psync -1
2、主节点解析发现是全量复制命令,则回复+FULLRESYNC响应
3、从节点接收响应数据并<b>保存运行ID和偏移量offset</b>
4、主节点开始执行bgsave保存RDB文件到本地
5、主节点发送RDB文件给从节点,从节点接收RDB文件并保存作为从节点数据文件
<b><font color="#ff0000">这里需要注意如果文件过大可能会导致总时间超过repl-timeout所配置的值(默认60秒)(也依赖网络情况)<br>一旦超过repl-timeout从节点将放弃接收RDB文件并清理已经下载的临时文件;<br>如果数据量较大(比如超过6G)则需要调大repl-timeout的值才可以;否则从节点会再次发起同步请求造成复制风暴</font></b>
无盘复制
为了降低主节点磁盘开销,可以开启无盘复制,生成的RDB文件不保存磁盘直接通过网络发给从节点
通过repl-diskless-sync参数控制,默认关闭
适用场景:磁盘性能较差但网络带宽较充裕的情况下
6、在从节点接收RDB快照期间,主节点可以继续响应读写命令,<br><b><font color="#c41230">主节点会把这期间的写命令保存在复制客户端缓冲区内<br></font></b>当从节点加载完RDB后,主节点再把缓冲区内的数据发送给从节点,保证主从之间数据一致性。
<font color="#ff0000">如果写操作很多的话有可能会导致复制客户端缓冲区溢出<br>默认配置为 <b>client-output-buffer-limit slave 256MB 64MB 60</b><br>60秒内缓冲区消耗持续大于64MB或者直接超过256M时,主节点将直接关闭复制客户端连接,造成全量同步失败</font>
全量同步失败日志如下:<br>M 27 May 12:13:33.669 # Client id=2 addr=127.0.0.1:24555 age=1 idle=1 flags=S<br>qbuf=0 qbuf-free=0 obl=18824 oll=21382 omem=268442640 events=r cmd=psync<br>scheduled to be closed ASAP for overcoming of output buffer limits.<br>
对于主节点,当发送完所有数据后就认为全量复制完成了
7、从节点接收完主节点传过来的全部数据的时候会清空自身旧数据
16:24:02.234 * MASTER <-> SLAVE sync: Flushing old data
8、从节点清空数据后会进行加载RDB文件,对于较大的RDB文件这一步是比较耗时的
因为在读写分离场景下,从节点还负责响应读命令;此时可能会出现数据过期或者错误的问题
slave-sever-stale-data 默认开启<br>开启的情况下从节点默认依然响应所有命令<br>如果不允许数据不一致则设置为no,此时从节点对除了info slave命令以外的所有命令,此时返回“SYNC with master in progress”
9、从节点成功加载完RDB后,如果当前节点开启了AOF持久化功能,则会立即开始做bgrewriteaof操作