主从结构
主从结构类似如下:
一个master对应多个slave,一个slave对应一个master。
master:写数据,并将数据同步到slave中(基本无读数据操作)
slave:读数据(基本无写数据操作)
优点:
1. 读写分离,提高服务器的读写负载能力
2. 故障恢复,当master出现故障,由slave提供服务
工作流程
1. 主从建立连接 slave连接master
2. 主从数据同步 master同步数据给slave
3. 主从命令传播 master反复同步新增数据给slave
建立连接
主从之间建立连接的发起方式有3种(从连主):
1. 客户端连接 命令:slaveof masterIP masterPORT
2. 启动当前服务器时指定 命令: redis-sever redis-conf slaveof masterIP masterPORT
3. 配置文件中配置(常用方式) salveof masterIP masterPORT
断开连接: slave no one
建立连接的过程步骤比较多,简单来说就是slave通过slaveof ip port建立与master的socket通信,成功后slave保存master的ip和port信息,master保存slave的port信息。
数据同步
连接建立后开始主从之间的数据同步
1. slave请求同步数据 slave发送指令: psync2 runid offset,首次发送时offset为-1
2. master通过bgsave创建rdb同步数据通过socket发送给slave,与此同时,将新进入的数据以指令的形式存入缓冲区(只存引起数据改变的指令)
3. slave回复rdb同步数据
4. slave请求部分同步数据
5. master将缓冲区的数据发送给slave
6. slave将接收的aof指令进行bgrewriteof重写(如由100条指令重写成10条有效指令)后执行,完成部分数据的同步
salve恢复rdb数据的过程为 全量复制
salve恢复缓冲区数据过程为 增量复制
在master同步数据阶段,全量数据之外的数据(增量数据)被放在复制缓冲区,缓冲区过小易导致溢出丢失数据,slave发现数据丢失会重新请求同步数据。
repl-backlog-size **mb 设置复制缓冲区大小
避免slave同步数据时服务器响应阻塞数据不同步,建议关闭此期间的对外服务
slave-serve-stale-data no
命令传播
master将接收到的能变更数据的指令发送给slave,slave接收执行后使主从数据一致。
当命令传播阶段出现断网现象时:
1. 闪断闪连 忽略
2. 短时间断网 增量复制
3. 长时间断网 全量复制
slave同步数据过程中使用的runid和offset:
服务器运行ID,称为runid,是服务器每次运行的识别码,多次运行会出现多个不同id。在服务器间进行传输识别身份,master据此判断不同的slave。
复制缓冲区:是一个FIFO的队列,存储master收到的影响数据变更的指令,超过缓冲区大小后,先进存入的指令会被弹出。
如以上指令存入复制缓冲区表现为如下形式
偏移量 (offset) | ... | 876 | 877 | 878 | 879 | 880 | 881 | 882 | 883 | 884 | 885 | 886 | 887 | 888 | 889 | 890 | 891 | 892 | ... |
字节值 | ... | $ | 3 | \r | \n | s | e | t | \r | \n | $ | 4 | \r | \n | n | a | m | e | ... |
通过runid和offset区分不同slave当前传播的差异,master记录已发送的offset,slave记录已接收的offset,两者一致时maser才会继续发送。
心跳机制
进入命令传播阶段,master与slave间要进行信息交换,使用心跳机制维护,实现双方连接在线。
master心跳:
指令: ping
周期: 10s
作用: 判断slave是否在线。
slave心跳:
指令: replconf {offset}
周期: 1s
作用: 1. 判断master是否在线; 2. 报告自己的offset,以获取最新的变更指令。