Redis高级应用--主从复制

简介

高并发

互联网架构追求高并发,高性能和高可用。其中高并发指允许大量用户同时访问,高可用指服务器宕机时间少。业界高可用目标为5个9,即可用性达到99.999%,也就是说服务器年宕机时长低于315秒,计算公式为:(31536000-宕机时间)/ 31536000 * 100% (31536000 = 365 * 24* 60 * 60=1年)

主从复制作用

1、读写分离:master写,slave读,提高服务器的读写负载能力
2、负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载,由slave提供服务,实现快速的故障恢复
3、故障恢复:当master出现问题时,由slave提供服务,实现快速的故障恢复
4、数据冗余:实现数据热备份,是持久化之外的一种数据冗余方式
5、高可用基石:基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

主从复制工作流程

主从复制可分为三个阶段:

  • 建立连接阶段
  • 数据同步阶段
  • 命令传播阶段

建立连接阶段工作流程

master slave
/ 1、发送指令:slaveof ip port
2、接收指令,响应slave /
/ 3、保存master 的ip和端口
/ 4、根据保存的信息创建连接master的socket
/ 5、周期性发送命令:ping
6、响应pong /
/ 7、发送指令:auth password
8、验证授权 /
/ 9、发送指令:replconflistening-port
10、保存slave的端口号 /

主从连接指令(slave使用)

方式一:客户端发送命令

1
slaveof <masterip> <masterport>

方式二:启动slave服务器时加参数

1
redis-server -slaveof  <masterip> <masterport>

方式三:服务器配置(保存在conf文件中)

1
slaveof <masterip> <masterport>

主从断开连接(slave使用)

slave客户端发送命令:

1
slaveof no one

数据同步阶段工作流程

master slave
/ 1、发送指令:psync2
2、执行bgsave /
3、第一个slave连接时,创建复制缓冲区(复制缓存区中保存生成RDB文件时master服务器执行的命令) /
4、生成RDB文件,通过socket发送给slave /
/ 5、接收RDB文件,清空数据,执行RDB文件恢复过程
/ 6、发送命令告知RDB恢复已经完成
7、发送复制缓冲区数据 /
/ 8、接收信息,执行bgrewriteaof,恢复数据

数据同步阶段,1-5称为全量复制,使用RDB方式同步;6-8称为部分复制,使用AOF方式同步。这是因为全量复制时,还会有master服务器还会执行指令,因此需要保存这些指令,待全量复制后,同步这一部分数据。

部分复制阶段

短时间断网,可以使用部分复制来实现同步,而不必全量复制。使用部分数据需要三个要素:

  • 服务器运行id(run id);
  • 主服务器的复制积压缓冲区
  • 主从服务器的复制偏移量

服务器运行id

  • 服务器运行id是每台服务器运行时的身份识别码,一台服务器运行多次可以生成多个运行id
  • 运行id由40位字符组成,是随机十六进制字符
  • 用于服务器之间传输,识别身份

复制缓冲区

  • 复制缓冲区又叫复制积压缓冲区,是一个先进先出的队列,用于存储服务器执行过的命令,每次传播命令,master将命令记下来,存储在复制缓冲区。例如下面命令:
    1
    set name gavin
    保存为AOF格式为:
    1
    2
    3
    4
    5
    6
    $3 \r\n  #3表示指令的大小
    set \r\n
    $4 \r\n
    name \r\n
    $5 \r\n
    gavin \r\n
    然后将上面的数据保存在复制缓冲区中,复制缓冲区由偏移量和字节值组成,字节值表示上面指令,偏移量表示每个字节值代表的递增编号:
偏移量 9041 9042 9043 9044 9045 9046 9047 9048 9049 9050 9051 9052 9053 9054
字节值 $ 3 \r \n s e t \r \n $ 4 \r

偏移量

  • 偏移量是一个数字,描述缓冲区中指令字节位置
  • master端每发送一次指令记录一次,slave端接收一次指令记录一次
  • slave断线后对比master和slave的差异,然后恢复数据
master slave
/ 1、发送指令: psync2 runid offset
2、执行bgsave生成RDB文件,记录当前复制偏移量offset /
3、发送+FULLRESYNC runid offset 发送RDB文件给slave /
/ 4、收到+FULLRESYNC 保存master的runid和offset,清空全部数据,接收RDB文件,恢复RDB数据
/ 5、发送命令:psync2 runid offset
6、接收命令,判断runid是否匹配,判断offset是否在复制缓冲区中 /
7、如果runid或offset有一个不满足,执行全量复制 /
7、如果runid或offset校验通过,offset与offset相同,忽略,不用执行同步 /
7、如果runid或offset校验通过,offset与offset不同,发送+ CONTINUE offset ,发送复制缓冲区中两个offset之间的数据 /
/ 8、收到+CONTINUE 保存master的offset接收 信息后,执行bgrewriteaof,恢复数据

命令传播阶段工作流程

心跳机制

  • master心跳:
    • 指令:PING
    • 周期:由repl-ping-slave-period决定,默认10秒
    • 作用:判断slave是否在线
    • 查询:INFO replication (获取slave最后一次连接时间间隔,lag维持在0或者1视为正常)
  • slave心跳
    • 指令:REPLCONF ACK {offset}
    • 周期:1秒
    • 作用:汇报slave自己的复制偏移量,获取追星数据变更指令,判断master是否在线
1
2
min-slaves-to-write 2  
min-slaves-max-lag 8

slave数量少于2个,或者所有slave的延迟都大于等于8时,此时master只能读,不能写,同时关闭数据同步功能。

命令传播

master slave
1、发送命令:ping 1、发送命令:replconf ack offset
2、接收命令,判断offset是否在复制缓冲区中 /
3、offset不在缓冲区,执行全量复制 /
3、如果offset在缓冲区,master的offset与slave的offset相同,忽略,不用执行同步 /
3、如果offset在缓冲区,master的offset与slave的offset不同,发送+ CONTINUE offset ,发送复制缓冲区中两个offset之间的数据 /
/ 4、收到+CONTINUE 保存master的offset接收 信息后,执行bgrewriteaof,恢复数据

数据同步说明

1、复制缓冲区大小设定不合理,会导致数据溢出。如进行全量复制周期太长,进行部分复制时发现数据已经存在丢失情况,必须进行第二次全量复制,导致slave陷入死循环,因此可以设置复制缓冲区大小:

1
repl-backlog-size 1mb

2、master单机内存占用主机内存比例不应过大,建议使用50%70%的内存,留下30%50%的内存用于执行bgsave命令和创建复制缓冲区。
3、为避免slave进行全量复制、部分复制时服务器响应阻塞或数据不同步,建议关闭此期间的对外服务

1
slave-serve-stale-data yes|no