Redis主从复制原理

1,旧版本(redis2.8以前)复制实现

1)sync(同步) + command propagate(命令传播)两个操作。
2)当slave向master发送slaveof命令时,首先执行sync同步操作。
sync执行过程
从服务器向主发送sync命令
主服务器执行bgsave命令生成rdb,发送到从,后续命令记录到缓冲区。
从服务器载入rdb,主服务器发送缓冲区命令到从。
3)命令传播
主服务器对从服务器执行命令传播操作,将自己执行的命令,发送给从服务器执行。
4)旧版本sync命令,对断线重复制效率很低。断线之后,会重新使用sync全量同步。
bgsave命令:耗费master大量的cpu、内存、磁盘I/O等
rdb传输:耗费网络资源,并且影响master的响应请求。

2,新版本复制实现

1)使用psync命令替换sync。
psync分为:完整重同步(同sync)部分重同步(用于断线后复制)
2)从服务器发送psync -> 主服务器返回+continue -> 主服务向从服务器发送断线期间的写命令。
3)部分重同步的实现
复制偏移量:replication offset,主、从服务器分别维护offset。主服务器每次向从传播n字节数据时,偏移量+n;从服务器接收n字节数据,偏移量+n。(通过对比offset可以判断主从同步状态)
复制积压缓冲区(repl-backlog-size):replication backlog,主服务器命令传播时,写命令发送给slave的同时,写入backlog中,并为每个字节标记offset。
断线重同步:slave发送psync + 自身offset -> master对比offset和backlog -> backlog存在offset则发送+continue使用部分重同步。
runID:服务器启动时生成run id,slave初次复制时,master将自己的id发送给slave保存。
4)psync命令
slave发送:psync ? -1 master返回:+fullresync
slave发送:psync offset master返回:+continue执行部分冲同步。

3,slaveof命令的实现

1)client向从服务器执行slaveof 127.0.0.1 6379,从服务器将master的ip和端口保存在redisServer结构的masterHost和masterport中,返回client OK,异步执行复制工作。
2)从服务器创建连向主服务器的socket,主服务器accept后,将从服务器作为master的一个client对待。
3)从服务器发送ping命令到主服务器,主服务器返回pong。
4)根据从服务器的masterauth选项和主服务器的requirepass选项进行身份验证。
5)从服务器发送replconf listening-port 12345,向master发送端口信息。master记录在redisClient的slave_listening_port字段中。
6)从服务器执行psync命令,主服务器进行命令传播。
7)从服务器发送心跳检测(1s一次)replconf ack ,用于检测主从网络连接、辅助实现min-slaves、检测命令丢失。

4,杂项

1)slaveof host port 丢弃旧数据集,向新的服务器进行同步
slaveof no one 关闭复制功能, 不会丢弃旧数据
2)slave不会过期key,只会等待master过期key。模拟一条del命令发送给slave。

你可能感兴趣的:(Redis主从复制原理)