架构拓扑
复制关系
参与复制的节点一般有主节点和从节点两部分构成,任何节点都只能有一个主节点,任何一个主节点都可以有多个从节点,数据只能由主节点向从节点进行复制传输,复制关系可以按照部署拓扑需要进行建立或解除。
建立
配置复制的方式有以下三种:
- 在配置文件中加入
slaveof {masterHost} {masterPort}
随Redis启动生效 - 在redis-server启动命令后加入
--slaveof {masterHost} {masterPort}
生效 - 直接使用命令:
slaveof {masterHost} {masterPort}
生效
断开
当不再作为从节点复制某个主节点数据时,执行slaveof no one
来断开主从关系,则当前节点停止复制数据。
切主操作流程如下:
- 断开与旧主节点复制关系
- 与新主节点建立复制关系
- 删除从节点当前所有数据
- 对新主节点进行复制操作
切换主节点后,从节点会清空之前所有数据
主从拓扑
简单一主一从
网络异常,图片无法展示
|
这是比较常用的主从拓扑设计,设计简单,较为实用,维护成本也低;不足就是节点少扩展性不高,也无法做到非常健壮的高可用集群。
星形一主多从
网络异常,图片无法展示
|
该拓扑是拥有多个从节点,在读写分离且读多写少的场景下可以发挥作用,拥有较好的灾备处理能力,不足之处是由于从节点过多会加重主节点的网络负载压力。
树状一主多从
网络异常,图片无法展示
|
树状拓扑是在星状拓扑的基础上进行扩展的,其设计思想是既保留多从节点保持较好的扩展性和灾备能力,又尽量不增加主节点的网络负载压力,其不足之处在于网络拓扑关系复杂,对后续维护和网络环境有很大要求。
从节点只读模式
从节点使用slave-read-only=yes
配置为只读模式。由于复 制只能从主节点到从节点,对于从节点的任何修改主节点都无法感知,修改 从节点会造成主从数据不一致。因此建议线上不要修改从节点的只读模式。
传输延迟控制
Redis中repl-disable-tcp-nodelay
参数用于控制是否关闭TCP_NODELAY
,默认关闭。
状态 |
作用 |
缺点 |
延迟性 |
关闭(默认) |
无论数据包大小会立即发送 |
占用网络资源 |
低 |
开启 |
合并较小的数据包合并发送 |
节省网络资源 |
高 |
复制命令
Redis中复制命令分为老的sync
和新的psync
,新命令psync
支持全量/部分复制,在异常断开后支持续传,而sync
仅支持全量复制。
sync全量复制
网络异常,图片无法展示
|
sync
命令交互过程如下
- [step-1] Master收到Slave的
sync
复制请求后执行bgsave
通过fork()
进程在Master中生成rdb
文件 - [step-2] 传输
rdb
文件到Slave节点
psync全量/部分复制
网络异常,图片无法展示
|
psync
命令提供了部分复制的功能,在主从断线后可以在断传处进行续传,减少了重复复制工作,减少恢复同步时间和网络资源消耗。
- [step-1] 当Slave节点接收到客户端发送的
slaveof
,Slave节点会判断自身是否首次复制
- 若非首次复制,则执行
psync <runid> <offset>
进行同步,runid
即Master的运行ID,offset
即已复制的水位偏移量 - 若首次复制,则执行
psync ? -1
进行同步,表示开始全量复制
- [step-2] Master接收Slave复制请求命令后会根据复制情况进行全量或部分复制的反馈
- 全量复制。
+ FULLRESYNC <runid> <offset>
- 部分复制。
+ CONTINUE
- [step-3] Slave开始复制Master数据
初次复制时,sync
和psync
几乎无任何性能差距,都是从头复制,psync
优点体现在断网续传上可以支持通过偏移量进行部分复制。
复制原理
网络异常,图片无法展示
|
- [step-1] 根据客户端发送到Slave的命令
slaveof {masterHost} {masterPort}
保存主节点信息,也就是保存要向谁发起复制 - [step-2] 根据保存的主节点信息建立socket连接请求
- [step-3] 建立socket后,并不能确保Master可以进行复制服务,有可能在处理Lua脚本等,因此此时发送
Ping
命令验证Master是否可以进行复制,当Master返回Pong
表明Master处于ready
状态,可以进行复制工作进行 - [step-4] 若配置权限校验则进行权限认证
- [step-5] Slave向Master发送自身可以进行复制工作的端口信息
- [step-6] 执行
sync
或psync
复制同步命令,执行上述介绍的命令交互过程 - [step-7] 经历了以上复制交互的准备工作后,进入到命令传播阶段,当Master有写命令时会进行Slave节点传播,在Slave节点复制完成后,Master、Slave数据保持一致
主从心跳判断机制:
- 主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通 信,通过client list命令查看复制相关客户端信息,主节点的连接状态为 flags=M,从节点连接状态为flags=S。
- 主节点默认每隔10秒对从节点发送ping命令,判断从节点的存活性 和连接状态。可通过参数
repl-ping-slave-period
控制发送频率。 - 从节点在主线程中每隔1秒发送
replconf ack {offset}
命令,给主节点 上报自身当前的复制偏移量。
replconf命令主要作用如下:
- 实时监测主从节点网络状态
- 上报自身复制偏移量,检查复制数据是否丢失,如果从节点数据丢失,再从主节点的复制缓冲区中拉取丢失数据
- 实现保证从节点的数量和延迟性功能,通过
min-slaves-to-write
、min- slaves-max-lag
参数配置定义。 主节点根据replconf命令判断从节点超时时间,体现在info replication
统计中的lag信息中,lag表示与从节点最后一次通信延迟的秒数,正常延迟应 该在0和1之间。如果超过repl-timeout配置的值(默认60秒),则判定从节点 下线并断开复制客户端连接。即使主节点判定从节点下线后,如果从节点重 新恢复,心跳检测会继续进行。
总结
- 合理规划Slave的网络拓扑,避免复制风暴产生给网络传输带来负载压力
- Master/Slave可以进行读写分离,Master负责写、Slave负责读,适合读多写少的场景,但是要充分考虑数据不一致存在延迟的情况,根据业务容忍情况来进行取舍和使用。一般情况下Redis的性能可以支持Master读写,更多的是前置代理节点进行水平扩展而非通过扩展Slave节点进行读写分离,后面会在深入介绍
参考
《Redis设计与实现》
《Redis开发与运维》