1.Redis复制原理:
- 从节点执行slaveof命令之后,保存主节点的信息直接返回,此时复制流程还未开始建立;
- 从节点内部通过每秒运行的定时任务维护复制相关逻辑, 当定时任务发现存在新的主节点后,会建立了一个端口为 24555的套接字,专门用于接受主节点发送的复制命令;
- 如果从节点无法建立连接,定时任务会无限重试直到连接成功或者执行 slaveof no one取消复制;
- 连接建立成功后从节点发送ping请求进行首次通信,检测主从之间网络套接字是否可用以及检测主节点当前是否可接受处理命令。
- 如果发送ping命令后,从节点没有收到主节点的pong回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会继续发起重连;
- 当主从复制连接正常通信后,主节点会把持有的数据全部发送给从节点,这部分操作是耗时最长的同步,当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,以保证主从数据一致性。
2.Redis主从复制,分为全量复制与增量复制:
2.1 全量复制:一般用于初次复制场景,Redis早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。
全量复制的时间开销:
- 主节点bgsave时间
- RDB文件网络传输时间
- 从节点清空数据时间
- 从节点加载RDB的时间
- 可能的AOF重写时间
全量复制时,Redis主进程会继续响应客户端的写请求,此时Redis会把这些写命令放到的复制缓冲区,等待RDB文件传输完成后,再发送给从节点去执行这些命令。
2.2 增量复制:用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发丢失数据给从节点。因为补发的数据远远小于全量数据,可以有效避免全量复制的过高开销。
增量同步通过psync命令运行,需要以下组件支持:
- 主从节点各自复制偏移量 (offset)
- 主节点复制积压缓冲区 (replication_backlog)
- 主节点运行id(replication id):个数根据从节点的数量而定。
增量同步时,Redis主进程会把收到的写命令放到复制积压缓冲区,如果从节点和主节点间发生了网络断连,等从节点再次连接后,可以从复制积压缓冲区中同步尚未复制的命令操作。
3.主从复制时需要注意的点:
3.1 保证从节点只读:
默认情况下,从节点使用slave-read-only=yes配置为只读模式。由于复 制只能从主节点到从节点,对于从节点的任何修改主节点都无法感知,修改 从节点会造成主从数据不一致。因此建议线上不要修改从节点的只读模式。
3.2 传输延迟:
主从节点一般部署在不同机器上,复制时的网络延迟就成为需要考虑的问题,Redis为我们提供了repl-disable-tcp-nodelay 参数用于控制是否关闭 TCP_NODELAY,默认关闭,说明如下:
- 当关闭时,主节点产生的命令数据无论大小都会及时地发送给从节 点,这样主从之间延迟会变小,但增加了网络带宽的消耗。适用于主从之间的网络环境良好的场景,如同机架或同机房部署。
- 当开启时,主节点会合并较小的TCP数据包从而节省带宽。默认发送时间间隔取决于Linux的内核,一般默认为40毫秒。这种配置节省了带宽但增大主从之间的延迟。适用于主从网络环境复杂或带宽紧张的场景,如跨机房部署。
运维建议:
部署主从节点时需要考虑网络延迟、带宽使用率、防灾级别等因素,如 要求低延迟时,建议同机架或同机房部署并关闭repl-disable-tcp-nodelay;如 果考虑高容灾性,可以同城跨机房部署并开启repl-disable-tcp-nodelay。
3.3 主从间的心跳检测:
- 主从节点在建立复制后,主节点会根据 repl-ping-slave-period 配置定时向从节点发送ping命令,判断从节点的存活性和连接状态,默认为10s。
- 从节点在主线程中每隔1秒发送replconf ack{offset}命令,实时监测主从节点网络状态,给主节点上报自身当前的复制偏移量,检查复制数据是否丢失。通过min-slaves-to-write、minslaves-max-lag参数配置,实现保证从节点的数量和延迟性功能。
- 设置合理的复制超时时间 repl-timeout:默认为60秒;
repl-timeout判断标准:
1)批量传输I/O在同步,从节点的观点。
2)从slave的角度来看主超时(数据,ping)。
3)从主服务器的角度来看从服务器超时(REPLCONF ACK ping)。
所以要确保repl-timeout > repl-ping-slave-period 的时间。