Redis 技术内幕——主从同步原理
Posted 一叶知秋V
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redis 技术内幕——主从同步原理相关的知识,希望对你有一定的参考价值。
单机 Redis 可能存在机器故障、容量瓶颈和 QPS 瓶颈。主从复制为一个数据提供了多个副本,扩展了读性能。一个 Master 可以有多个 Slave,一个 Slave 只能有一个 Master,Redis 数据流向是单向的,Master 到 Slave。
主从同步存在的问题?需要手动故障转移。
1.主从同步实现方式
主从同步有两种实现方式:
1、slaveof 命令实现
在 Slave 上执行 slaveof [master_ip master_port] 命令即可,slaveof 命令是异步的。取消复制只需要在 Slave 上执行 slaveof no one 命令即可,取消复制并不会清除之前复制过的数据。
优点是无需重启,缺点是不便于管理。
2、redis.conf 配置文件实现
在 redis.conf 中添加 slaveof master_ip master_port 配置即可,如果希望 Slave 只读,可以增加 slave-read-only yes 配置。
优点是统一配置,缺点是需要重启。
建议第一次启动可以使用 redis.conf 配置文件实现,后期运维可以考虑使用命令实现。
2.全量同步和增量同步
主从同步主要分为全量同步和增量同步。
全量同步过程:
- slave 发送 sync 命令到 master;
- master 启动一个后台进程,将 Redis 中的数据快照保存到文件中(bgsave);
- master 将保存数据快照期间接收到的写命令缓存起来(AOF);
- master 完成写文件操作后,将该文件发送给 slave;
- 使用新的 RDB 文件替换掉旧的 RDB 文件;
- master 将这期间收集的增量写命令发送给 slave;
增量同步过程:
- master 接收到用户的操作指令,判断是否需要传播到 slave,增删改需要传播,查不传播;
- 将操作记录追加到 AOF 文件;
- 将操作传播到其他 slave:对齐主从库;往响应缓存写入指令;
- 将缓存中的数据发送给 slave。
两个概念:
runid:Redis 每次启动的时候都会有一个随机 ID 作为 Redis 的标识,重启之后会发生变化。
offset:复制偏移量。在 master 和 slave 中都会有 offset。master 传输出去 N 个字节,master 的 offset 增加 N;slave 收到 N 个字节,slave 的 offset 增加 N。
全量复制原理:
首先将 master 本身的 RDB 文件同步给 slave,而在同步期间,master 写入的命令也会记录下来(master 内部有一个复制缓冲区,会记录同步时 master 新增的写入),当 slave 将 RDB 加载完后,会通过偏移量的对比将这期间 master 写入的值同步给 slave。
为什么要增量复制?
在 Redis 2.8 版本之前,如果 master 和 slave 之间的网络发生了抖动连接断开,就会导致 slave 完全不知道 master 的动作,同步就会出问题,而为了保证数据一致,等网络恢复后进行一次全量复制。而全量复制的开销是很大的,Redis 2.8 版本就提供了一个增量复制的功能。
增量复制的实现原理:
当 master 和 slave 断开连接时,master 会将期间所做的操作记录到复制缓存区当中(可以看成是一个队列,其大小默认 1M)。待 slave 重连后,slave 会向 master 发送 psync 命令并传入 offset 和 runId,这时候,如果 master 发现 slave 传输的偏移量的值,在缓存区队列范围中,就会将从 offset 开始到队列结束的数据传给 slave,从而达到同步,降低了使用全量复制的开销。
3.故障处理
主从复制中处理故障转移分为 slave 宕掉和 master 宕掉两种情况。
slave 宕掉故障处理:
slave 宕掉后,对于 master 无影响,只是对 slave 有影响,一般来说会将 宕掉 slave 的流量切到正常的 slave 节点上。
master 宕掉故障处理:
master 宕掉后,相对比较麻烦,master 读写节点是无法对外提供服务的,slave 只读节点是无影响的,最常见的方案就是将一个 slave 切为 master,选择一个 slave 节点执行 slaveof no one 命令让它成为一个 master,然后对其余的 slave 执行 slaveof new master 命令。
也可以看出,主从复制这个模型没有实现真正的自动故障转移(一个服务挂掉了,另一个服务可以自动顶上来,把故障自动转移掉)。Redis 自动故障转移提供了 Redis Sentinel。Redis Sentinel 见。
4.常见问题
1、读写分离问题
读流量分摊到从节点。可能遇到的问题:复制数据延迟;读到过期数据;从节点故障。
2、配置不一致问题
例如 maxmemory 不一致,会导致丢失数据;
例如数据结构优化参数 hash-max-ziplist-entries 不一致,会导致内存不一致。
3、规避全量复制
第一个场景:第一次全量复制。
第一次挂 slave 节点不可避免。
第二个场景:节点运行 ID 不匹配。
主节点重启(runid 变化)。可以采用故障转移的方式避免,例如哨兵或集群。
第三个场景:复制积压缓冲区不足。
默认值 1MB,例如网络中断,部分复制无法满足则会进行全量复制。可以通过增大复制缓冲区配置 rel_backlog_size 避免。
4、规避复制风暴
单节点复制风暴:
问题:主节点重启,多从节点复制
解决:更换复制拓扑。master -> slave 变为 master -> slave-1 -> slave-1-a 。
单机器复制风暴:
问题:机器宕机后,大量全量复制。
解决:主节点分散多机器。
以上是关于Redis 技术内幕——主从同步原理的主要内容,如果未能解决你的问题,请参考以下文章