文章目录
主从复制
- 一个主机master与多个从机slave集群,一般主机只写入数据,并同步给从机,从机只读取数据。
- 从机通过指令
slaveof
host port
成为master的slave - 需要取消主从关系, slave可以通过指令
slaveof no one
解除 - 使用
info [filter]
指令查看master或slave(指定)信息
master与slave通信过程
- slave主动向master建立连接
- 数据同步
- 命令传播
建立连接
- slave -> 执行指令
slaveof
host port
,向master确认请求建立连接 - master -> 响应slave
- slave -> 保存master的IP和端口,建立socket连接,并周期性探测**
ping
** master - master -> 响应 pong
- slave -> 发送指令
auth password
- master -> 验证授权
- slave-> 发送指令
replconf listening-port <port-number>
- **master -> ** 保存slave端口号,连接建立完成
数据同步与传播 - 1(socket)
- slave -> 发送数据同步指令
psync2
- master -> 执行RDB备份,同时创建命令缓冲区保存新入指令,先同步RDB备份(全量复制-1)
- slave -> 接收RDB备份,清空本地数据,恢复RDB数据(全量复制-2)
- slave -> 恢复完成向master报告确认数据同步点offset
- master -> 比较offset,发送命令缓冲区数据(增量复制-1)
- slave -> 接收指令,执行
bgrewriteaof
,恢复数据(增量复制-2) - slave -> 周期性发送数据同步offset确认
- master -> 响应指令,同步数据
补充
- 主机和从机都具有唯一的40位16进制run_id,用于识别身份。
- 主从机通信过程都会先发送目标run_id,目标机根据run_id判断是否是发送给自己的。
- master同步数据过程有指令缓冲区,缓存指令,对应有offset偏移量,在slave同步时发送缓冲区对应数据
- 指令缓冲区耗尽后slave依然未同步最先的数据的话,缓冲区溢出会使开始的数据丢失,此时slave同步offset无法对应,所以会进入全量复制过程
数据同步与传播 - 2
- slave -> 发送指令
psync2 ? -1
请求初始数据同步(psync2
<run_id> <offset>
) - master ->
bgsave
执行RDB备份, 记录当前offset- 发送
+FULLRESYNC
run_id offset
, 通过socket发送RDB备份数据 - 期间master收到新指令, 缓存到指令缓冲区, 标记offset
- slave ->
- 收到
+FULLRESYNC
- 保存master的run_id和offset
- 清空本地数据, socket接收RDB数据, 恢复备份
- 收到
- slave -> 发送指令
psync2
run_id offset
- master ->
- 匹配run_id, 比较offset在缓冲区的位置
- run_id或offset异常, 则进入全量复制过程
- 本地offset相同, 则忽略本次请求
- 本地offset不同, 发送
+CONTINUE
offset
更新slave的数据同步点, 并通过socket发送对应缓冲区数据
- slave ->
- 收到
+CONTINUE
- 保存master的offset
- socket接收同步数据, 执行
bgrewriteaof
, 恢复数据
- 收到
心跳机制
- master心跳:
- 指令:
PING
- 周期: 由
repl-ping-slave-period
决定, 默认10秒 - 作用: 判断slave是否在线
- 通过`info replication查询slave最后一次连接时间间隔lag
- 指令:
- slave心跳:
- 指令:
REPLCONF ACK
offset
- 周期: 1秒
- 作用: 确认数据同步点offset, 同步最新数据; 判断master是否在线
- 指令:
主从复制问题
频繁进行全量复制
- master重启, run_id发生变化, 导致所有slave需要进行全量复制
- master内部有master_replid变量, 41位id, 发送给slave
- master关闭执行
shutdown save
时, runid和offset也会写入RDB文件- repl-id / repl-offset, 通过终端
redis-check-rdb
rdbfile
可以查看RDB内的信息
- repl-id / repl-offset, 通过终端
- master重启加载RDB文件, 会将repl-id和repl-offset加载到内存
- slave会认为还是之前的master
- 网络环境不佳, slave服务异常
- 原因: 复制缓冲区过小, slave工作不稳定, offset容易越界
- 解决: 增加缓冲区大小
repl-backlog-size
- 一般计算: 2 × master与slave的平均网络连接延迟 × master平均每秒指令数量
频繁中断主从连接
- slave接收到慢查询指令, 无法响应master, 连接被释放, slave恢复后又重新建立连接
- 设置master适当的超时时间, 释放slave
- 配置
repl-timeout
, 默认60秒
- 配置
- 设置master适当的超时时间, 释放slave
- master发送
ping
指令数据丢包- 提高
ping
指令的发送频率, 多次重复检测心跳- 配置
repl-ping-slave-period
, 一般repl-timeout
时间内需要5-10次ping
- 配置
- 提高
多slave间数据不同步
- slave网络信息不同步, 数据有延迟
- 分布式网络总会存在数据不同步的现象
- 对于同步要求不严格的服务,可以监控slave节点延迟, 如果offset延迟过大, 则暂时关闭对该slave的数据访问
- 开启
slave-serve-stale-data
yes|no
状态, slave将只响应少数控制指令
- 开启
- 对部分同步需求高的数据,可以单独设立服务器用于读写数量数据。