Redis高级——主从复制

什么是主从复制

在分布式系统中,一台 Redis 服务器的数据自动复制(同步)到其它的 Redis 服务器上,称为主从复制,其中前者称为主节点(Master),后者称为从节点(Slave),主节点负责写入数据、从节点负责读取数据

一般来说,数据流动是单向的,只能从主节点流向从节点

一个主节点可以对应多个从节点,一个从节点只能对应一个主节点


主从复制的作用

读写分离

主节点提供写服务,从节点提供读服务,将读写分开,提高服务器的负载能力

负载均衡

根据需求的变化,可以改变从节点的数量,多个从节点分担数据读取任务,大大提高 Redis 服务器的并发量和数据吞吐量

故障恢复

当主节点出现故障时,可以由从节点提供服务,实现快速的故障恢复

数据备份

实现了数据的热备份,是持久化之外的另一种数据备份方式

高可用基石

主从复制是构建哨兵模式和集群的基础


主从复制的工作流程

建立连接

  • 设置 master 的 IP 和端口,保存 master 信息
  • 根据保存的信息创建连接 master 的 socket
  • slave 周期性向 master 发送 ping 指令,确保连接正常
  • slave 发送 auth password 指令进行权限验证(如果 master 设置密码)
  • slave 向 master 发送自身的端口信息,master 保存该信息

从节点客户端指令连接

从节点客户端发送 slaveof 指令,连接指定的主节点

slaveof host port

从节点配置启动参数连接

从节点启动时,设置启动参数进行连接

redis-server --slaveof host port

从节点配置文件设置连接

在从节点的配置文件中,增加如下配置进行连接

slaveof host port

数据同步

服务器运行ID

每一台服务器每一次运行的身份识别码称为服务器运行ID(runid),由 40 位随机的 16 进制字符组成

复制积压缓冲区(replication backlog buffer)

复制积压缓冲区是一个先进先出的队列,每次 master 向 slave 传播命令时,命令也存储到复制积压缓冲区中,当 master 与某个 slave 的发生连接中断,再次连接后可从复制积压缓冲区中同步尚未复制的命令

复制积压缓冲区由两部分组成:复制偏移量(offset)和字节值(用于存储命令对应的编码字符)

当入队元素的数量大于队列长度时,最先入队的元素会被强制出队,所以当 master 和 slave 的连接中断时间过长,导致复制积压缓冲区丢失了一些数据时,只能进行全量复制

通常复制积压缓冲区简称为复制缓冲区

复制偏移量

参与复制的主从节点都会维护自身的复制偏移量

主节点在处理完写入命令后,会把命令的字节长度进行累加,存储在 info relication 中的 master_repl_offset 中

从节点每秒向主节点上报自身的复制偏移量,因此主节点也会保存从节点的复制偏移量

从节点在接收到主节点发送的命令后,对自身的偏移量进行相应的累加,存储在 info relication 中的 slave_repl_offset 指标中

通过对比主从节点的复制偏移量,来判断主从节点数据是否一致,以及根据复制偏移量的差异,来判断主从节点数据同步延迟大小

同步过程

全量复制

  • slave 向 master 发送 psync2 指令请求同步数据,第一次发送 psync2 ? -1 ,因为第一次不知道 master 的 runid ,自己也没有 offset
  • master 执行 bgsave 指令生成此时的数据快照 RDB 文件,同时 master 创建复制缓冲区(replication_buffer)存储此后的写命令
  • master 通过 socket 将 RDB 文件以及 runid 和 offset 发送给 slave
  • slave 保存 master 发来的 runid 和 offset ,并删除所有旧数据,执行 RDB 文件恢复过程

增量复制(部分复制)

  • slave 向 master 发送 psync2 runid offset 命令
  • master 接受命令,比对 runid 是否匹配,offset 是否在复制缓冲区中
  • 如果 runid 与 offset 有一个不满足,执行全量复制(runid 不满足说明不是同一台服务器,offset 不满足说明复制缓冲区溢出,丢失了一些数据)
  • 如果 runid 与 offset 满足,master 与 slave 的 offset 相同,则不做处理(说明数据已经同步)
  • 如果 runid 与 offset 满足,master 与 slave 的 offset 不相同,master 将复制缓冲区中的数据,连同 offset 一并发给 slave
  • slave 保存 master 的 offset ,并对收到的复制缓冲区的指令进行重写后执行

从 slave 发送 psync2 ? -1 指令开始,到 slave 收到 RDB 文件执行恢复数据任务,并保存传来的 runid 和 offset 的过程,称为全量复制

从 slave 发送 psync2 runid offset 指令开始,进行 runid 和 offset 的比对,并将复制缓冲区的数据从 master 发送到 slave ,slave 保存新的 offset 的过程,称为增量复制(部分复制)

命令传播

在数据同步完成后,如果主节点再次收到写命令,该命令会自动传到各个从节点,保证各个从节点的数据同步,这个过程称作命令传播

心跳机制

在命令传播阶段,master 和 slave 之间需要进行信息交换,使用心跳机制进行维护

master 心跳

  • 指令:ping
  • 周期:由配置文件中的 repl-ping-slave-period 决定,默认 10 秒
  • 作用:判断 slave 是否在线
  • 查询:info replication 中 slave 的 lag 项为 0 或 1 表示正常

slave 心跳

  • 指令:replconf ack offset
  • 周期:1 秒
  • 作用:向 master 发送复制偏移量,获取新数据,并判断 master 是否在线

同步过程

与数据同步阶段的增量复制类似,但无需比对 runid ,slave 向 master 发送 replconf ack offset

  • 如果 offset 不在 master 的复制缓冲区,执行全量复制
  • 如果 offset 在 master 的复制缓冲区,且 master 与 slave 的 offset 相同,则不做处理
  • 如果 offset 在 master 的复制缓冲区,但 master 与 slave 的 offset 不相同,master 将复制缓冲区中的数据,连同 offset 一并发给 slave
  • slave 保存 master 的 offset ,并对收到的复制缓冲区的指令进行重写后执行

断开连接

从节点客户端发送指令,断开与主节点的连接

slaveof no one

授权访问

  • master 配置文件设置密码
requirepass password
  • master 客户端设置密码指令
config set requirepass password
  • master 客户端获取密码指令
config get requirepass
  • slave 客户端输入密码指令
auth password
  • slave 配置文件设置登陆密码
masterauth password
  • slave 启动参数设置登陆密码
redis-cli -a password

数据同步注意事项

  • 当 master 数据量过大时,应该避开流量高峰期,以免造成 master 阻塞
  • 复制缓冲区设置过小或全量复制时间过长时,可能会造成复制缓冲区数据溢出,会重新进行全量复制,导致死循环,可以在配置文件中设置复制缓冲区大小
    repl-backlog-size 1mb
  • 为了避免 slave 在主从复制期间响应请求导致数据不同步,设置该期间阻塞所有请求
    slave-serve-stale-data yes
  • 避免多个 slave 同时请求数据同步对带宽造成巨大冲击,适量错峰
  • slave 过多时,可考虑调整拓扑结构为树形结构,中间层节点既是 master 又是 slave ,但会导致深层次的 slave 数据同步延迟较大

Guess you like

Origin blog.csdn.net/qq_25274377/article/details/120817402