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将命令记下来,存储在复制缓冲区。例如下面命令:保存为AOF格式为:
1
set name gavin
然后将上面的数据保存在复制缓冲区中,复制缓冲区由偏移量和字节值组成,字节值表示上面指令,偏移量表示每个字节值代表的递增编号: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 | min-slaves-to-write 2 |
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 |