简介
高并发
互联网架构追求高并发,高性能和高可用。其中高并发指允许大量用户同时访问,高可用指服务器宕机时间少。业界高可用目标为 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 使用)
方式一:客户端发送命令
slaveof <masterip> <masterport>
方式二:启动 slave 服务器时加参数
redis-server -slaveof <masterip> <masterport>
方式三:服务器配置(保存在 conf 文件中)
slaveof <masterip> <masterport>
主从断开连接(slave 使用)
slave 客户端发送命令:
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 将命令记下来,存储在复制缓冲区。例如下面命令:
set name gavin
保存为 AOF 格式为:
$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 是否在线
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 陷入死循环,因此可以设置复制缓冲区大小:
repl-backlog-size 1mb
2、master 单机内存占用主机内存比例不应过大,建议使用 50%~70% 的内存,留下 30%~50% 的内存用于执行 bgsave 命令和创建复制缓冲区。
3、为避免 slave 进行全量复制、部分复制时服务器响应阻塞或数据不同步,建议关闭此期间的对外服务
slave-serve-stale-data yes|no
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于