reids之主从复制

集群

集群的优势

  • 如果只是单机,如果是出现机器故障,数据会丢失,而且会对业务造成灾难性打击
  • 单机会有容量瓶颈,单机容量有限,用完就完了
  • 集群就是避免redis服务器故障,准备多台服务器,复制数据在多个服务器上,保证数据是一致的,实现redis的高可用和数据的冗余备份

主从复制

  • 集群自然有一个主要的服务器,也就是master,也称为主节点,主库,主客户端,主服务器,负责提供数据
  • 接受数据,slave,也就是从库,从节点,从客户端
  • 最核心的工作就是主从复制,同步数据

主从复制的作用

  • 读写分离:master写,slave读.提高服务器的读写能力
  • 负载均衡:主从结构,slave分担master压力,提高服务器并发量和数据吞吐量
  • 故障恢复:master出现问题,有slave接收.快速故障恢复
  • 数据冗余:数据热备份,是持久化之外另一种数据冗余方式(也就是不需要每次都从rdb或者aof中恢复数据,从另外一个slave中读取也是可以的)
  • 高可用基石:基于主从复制可以构件哨兵模式和集群,实现高可用

主从复制的阶段

  • 建立链接阶段(准备阶段)
  • 数据同步阶段
  • 命令传播阶段

建立链接阶段

  • 流程
    • slave设置master的地址和端口,保存master信息
    • 建立socket链接
    • 发送ping命令,定时器任务(默认1s一次,而master向slave是10s一次)
    • 身份验证(基本不需要,在内网工作,不提供外网访问接口)
    • 发送slave端口信息(结束后,主从链接成功)
      在这里插入图片描述

slave连接master方式

  • 主从链接(slave链接master)
    • 方式1:客户端发送命令
      slaveof <masterip> <masterport>
    • 方式2:启动服务器参数
      redis-server -- slaveof <masterip> <masterport>
    • 方式3:服务器配置
      slave <masterip> <masterport>

授权访问

  • master配置文件设置密码
    requirepass <password>
  • master 客户端发送命令设置密码
    config set requirepass <password>
    config set requirepass
  • slave客户端发送命令设置密码
    auth <password>
  • slave 配置文件设置密码
    masterauth <password>
  • 启动客户端设置密码
    redis-cli -a <password>

数据同步阶段工作流程

  • slave向master请求同步数据
  • master创建RDB(bgsave)同步数据,并传给slave
  • slave恢复RDB同步数据
  • slave向master请求同步部分数据(从创建EDB之后这段时间新增的aof文件),master传给slaveAOF文件
  • slave同步AOF文件(结束)
    在这里插入图片描述

数据同步阶段master说明

  • 如果master数据量巨大,数据同步阶段应避开流量高峰期,影响业务正常执行
  • 复制缓冲区大小设定不合理,会导致数据溢出,如进行RDB周期太长,进行AOF时发现数据已经存在丢失的情况,会进行第二次RDB,导致slave陷入死循环
    repl-backlog-size 1mb 配置缓冲区大小
  • master单机内存占用主机内存的比例不应过大,建议使用50%~70%的内存,剩下的内存执行bgsave命令和创建缓冲区

数据同步阶段slave说明

  • 为了避免slave进行RDB,AOF时服务器响应阻塞或数据不同步,建议关闭此期间的对外服务
    slave-serve-stale-date yes|no
  • 数据同步阶段,master发送给slave信息可以理解master是slave的一个客户端,主动向slave发送命令
  • 多个slave同事对master请求数据同步,master发送的RDB文件增多,会对带宽造成巨大冲击,如果master带宽不足,数据同步最好是适当错峰
  • slave过多时,建议调整拓扑结构,由一主多从结构编程树状结构,中间的节点是master,也是slave,然后在同步给自己的slave,但是这样导致深度的slave和最顶层的maser之间数据同步延迟较大,数据一致性变差

命令传播阶段

  • 当master数据库状态被修改后,导致主从服务器数据库状态不一致,此时需要让主从数据同步一致的状态,同步的动作称为命令传播
  • master将接收到的数据变更命令发送给slave,slave接收命令后执行命令
  • 如果命令传播阶段出现了断网现象
    • 网络闪断闪连 忽略
    • 短时间网络中断 进行增量复制(AOF)
    • 长时间网络中断 进行全量复制(RDB)
  • 部分复制的三个核心要素
    • 服务器的运行id(run id)
    • 主服务器的复制积压缓冲区
    • 主从复制的复制偏移量

服务器的运行id

  • 概念:服务器运行id是每一个服务器每次运行的身份证识别码.一台服务器多次运行可以产生多个运行id
  • 组成:由40个字符组成,是一个随机的十六进制字符
  • 作用:runid被用于在服务器间进行传输,识别身份,如果想两次操作都对同一台服务器进行,必须每次操作携带对应的运行id,用于对方识别
  • 实现方式:运行id在每台服务器启动时自动生成,master在首次连接slave时,会将自己的运行id发送个slave,slave保存此id,通过info server命令,可以查看额节点的runid

复制缓存区

  • 概念:被称为复制积压缓冲区,是一个先进先出的队列,用于存储服务器执行过的命令,每次传播命令,master都会讲传播的命令记录下来,并存储在复制缓冲区
  • 复制缓冲区默认数据存储空间大小是1m,由于存储空间大小是固定的,当入队元素的数量大于队列长度时,最先入队的元素会被弹出,而新元素会被放入队列
  • 由来:服务器启动时,如果有启动aof或者是master节点,就会创建复制缓存区
  • 作用:用于保存master收到的所有命令,(只有影响数据变更的命令)
  • 数据来源:当master接收到主客户端的指令时,除了将指令执行,会将该指令存储到缓冲区中
  • 工作原理
    • 由偏移量(offset)和字节值组成
    • 通过offset区分不同的slave和当前数据的差异
    • master记录已发送的信息对应的offset
    • slave记录已接收到的信息对应的offset
    • 两个offset之间的差异就是还没有同步的信息
    • 字节值的内容是aof里面的值,以下图,然后取两个offset之间的值即可同步过去在这里插入图片描述

主从服务器复制偏移量(offset)

  • 概念:一个数字,描述复制缓冲区的指令字节位置
  • 分类
    • master复制偏移量,记录发送给所有slave的指令字节对应的位置(多个)
    • slave复制偏移量,记录slave接收master发送的指令字节对应的位置(一个)
  • 数据来源:
    • master:发送一次,记录一次
    • slave接收一次,记录一次
  • 作用:同步信息,比对master和slave的差异,当slave断线后,恢复数据用在这里插入图片描述

心跳机制

  • 进入命令传播阶段,master和slave间需要进行信息交换,使用心跳机制进行维护,实现双方连接报纸在线
  • master心跳
    • 指令:ping
    • 周期:由repl-ping-slave-period决定,默认10s
    • 作用:判断slave是否在线
    • 查询INFO replication,获取slave最后一次连接时间间隔,lag项维持在0或1视为正常
  • slave心跳机制
    • 指令:REPLICONF ACK{offset}
    • 周期:1s
    • 作用
      • 汇报slave自己的复制偏移量,获取最新的数据变更指令
      • 判断master是否在线

心跳阶段注意事项

  • 当slave多数掉线,或者延迟过高时,master为保障数据稳定性,将拒绝所有信息同步操作
    min-slave-to-write 2
    min-slave-max-lag 10
    • 以上配置的意思是slave数量少于2个,所有slave的延迟都>=10s时,强制关闭master写功能,停止数据同步
  • slave数量由slave发送REPLCONF ACK命令做确认
  • slave延迟由slave发送REPLCONF ACK命令做确认

在这里插入图片描述

常见问题

频繁的全量复制(1)

  • maste的数据量比较大的时候,如果master重启,runid发生变化,导致全部slave的全量复制操作
  • 解决方法
    • master内部创建master_replid变量,使用runid相同策略生成,长度41位,并发送给所有slave
    • 在master关闭时执行命令shutdown save,进行RDB持久化,将runid和offset保存到RDB文件中,
      • repl_id repl_offset
      • 通过redis-check-rdb命令可以查看该信息
    • master重启后加载RDB文件,恢复数据,将RDB中保存的repl_id 和repl_offset加载到内存中
      • master_repl_id = repl_id
      • master_repl_offset = repl_offset
      • 通过info命令可以查看该信息
  • 作用:本机保存上次的runid重启后恢复该值,使所有slave认为还是之前的master

频繁的全量复制(2)

  • 问题现象:网络环境不佳,出现网络中断,slave不提供服务
  • 问题原因:复制缓冲区过小,断网后的slave的offset越界,触发全量复制
  • 最终结果:slave反复进行全量复制
  • 解决方案:修改复制缓冲区大小
    repl-backlog-size
  • 建议
    • 测算从master到slave的重连平均时长second
    • 获取master平均每秒产生写命令总数量:write_size_per_second
    • 最优复制缓冲区空间= 2* second* write_size_per_second

频繁的网络中断(1)

  • 问题现象:master的cpu占用过高或slave频繁断开连接
  • 问题原因
    • slave每秒发送REPLCONF ACK命令道master
    • 当slave街道慢查询时,会占用大量cpu性能
    • master每秒调用复制定时函数replicationCron(),比对slave发现长时间没有进行响应
  • 最终结果:master各种资源被严重占用
  • 解决方案:通过设置合理的超时时间,确认是否释放slave
    repl-timeout

频繁的网络中断(2)

  • 问题现象:slave和master链接断开
  • 问题原因
    • master发送ping指令频度较低
    • master设定超时时间较短
    • ping指令在网络中丢包
  • 解决方案:提高ping指令发送的频度,超时时间至少是ping指令的5~10倍,否则slave很容易判定超时
    repl-ping-slave-period

数据不一致

  • 问题现象:多个slave获取相同数据不同步
  • 问题原因:网络信息不同步,数据发送有延迟
  • 解决方案
    • 优化主从间的网络环境,通常繁殖在同一个机房部署,云服务器要注意
    • 监控主从节点延迟(通过offset)判断,如果slave延迟过大,暂时屏蔽程序对改slave的数据访问
      slave-serve-stale-data yes|no