概念
- 主从服务器:假设有两台服务器,分别为:127.0.0.1:12345和127.0.0.1:6379
127.0.0.1:12345> SLAVEOF 127.0.0.1:6379
OK
通过SLAVEOF命令,使得127.0.0.1:12345成为127.0.0.1:6379从服务器。即此时:
从服务器(slave):127.0.0.1:12345
主服务器(master):127.0.0.1:6379
2. 从服务器复制主服务器,进行复制后的主从服务器的数据库数据保持一致——数据库状态一致,简称一致。
复制实现
Redis复制在2.8以前和2.8及其以后是不一样的实现方式。
旧的复制实现(2.8以前)
存在的问题:
在第一次主从复制时,旧的复制能够很好地完成任务。
但在断线重连时,这样的复制效率会很低。每次SYNC时,都会把主服务器的全部数据库状态复制到从服务器,而断线重连只需要断线后的部分数据就行。
新的复制实现
在2.8版本及以后,就用PSYCN代替了SYNC。它有两种模式:完整重同步 和 部分重同步
三个词:
名称 | 概念 |
---|---|
复制偏移量 | 主服务器每次向从服务器传播N个字节的数据时,就会将自己的复制偏移量加上N;从服务器每次收到主服务器传播过来的N个字节的数据时,就会将自己的复制偏移量的值加上N |
复制积压缓冲区 | 服务器维护的一个固定长度的先进先出的队列,默认大小为1MB。复制积压缓冲区会保存一部分最近传播的写命令,并为队列中的每个字节记录相应的复制偏移量 |
服务器运行ID | 每个redis服务器都有自己的运行ID,由40个随机的十六机制字符组成,用于判断断线重连后是否是之前的服务器 |
复制的实现
- 向从服务器发送SLAVEOF命令
127.0.0.1:12345>127.0.0.1:6379
OK
- 设置主服务器的地址和端口
strcut redisServer{
char *masterhost //127.0.0.1
int masterport //6379
}
此时从服务器向客户端返回一个OK,表示复制指令已被接收。此时开始执行复制工作。
- 建立套接字连接
从服务器创建连向主服务器的套接字。
- 发送PING命令
PING命作用:
·验证套接字的读写状态是否正常
·检查主服务器能否正常处理命令请求
- 身份验证
- 发送端口信息
从服务器将执行以下命令 ,向主服务器发送从服务器监听端口号
主服务器接收后,将会存储在客户端状态的slave_listening_port属性中。REPLCONF listening-port <port-number>
- 同步
- 命令传播
完成同步之后,主从服务器就会进入命令传播阶段,主服务器将自己执行的写命令发送给从服务器,是的双方数据保持一致。
命令传播阶段有一个心跳检测:即每隔一秒钟,从服务器就会向主服务器发送命令:
REPLCONF ACK <replication_offset>
心跳检测作用:
· 检测主从服务器的网络连接状态:如果主服务器超过1s没有收到REPLCONF ACK命令,那么主服务器就能知道两者之间的网络连接出现问题;
· 辅助实现min-slaves配置选项
· 检测命令的丢失:如果从服务器发送的offset复制偏移量与自己不一致,主服务器就知道从服务器缺少数据,在复制积压缓冲区中找到缺少的数据发送给从服务器。