Redis的主从复制
单机服务的问题:
- Redis服务故障,可能会造成数据丢失
- QPS支撑不够,利用主从集群,主从复制,实现读写分离
主从复制:
在Redis中,用户通过执行SLAVEOF命令或配置slaveof选项,让一个服务器去复制另一个服务器,被复制的服务器为master,进行复制的服务器为从slave。主节点负责写数据,从节点负责读数据,主节点定期把数据同步到从节点保证数据一致性。
- 异步复制方式复制数据到slave节点,redis2.8开始,slave会周期性地确认自己每次复制的数据量
- slave复制时不阻塞master正常工作,也不会阻塞对自己的查询,会用旧数据集提供服务,但是复制完成时,需删除旧数据集加载新数据集,这时候会暂停对外服务
- 采用主从架构master必须开启持久化,不建议用salve做为master的数据热备,因为如果关掉master的持久化,master宕机重启时数据是空的,可能经过复制,slave数据也丢失了
- 即使使用哨兵,也可能哨兵还没有检测到master failure,master就自动重启了,还是会导致复制后slave数据也丢失
主从复制作用:
- 提供多个数据副本、通过读写分离扩展读性能、避免单机故障
- 支持一主多从,但一个slave只能有一个master。数据流向是单向的,master到slave
全量复制:用于初次复制或其它无法进行部分复制的情况,重型操作,数据量大时会对主从节点和网络造成很大的开销

部分复制(断点续传):处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,可以接着上次复制的地方继续复制。如果网络中断时间过长,造成主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制
复制偏移量(offset):
- 参与复制的主从节点都会维护自身的offset,master处理完写命令后,会把命令的字节长度做累加,存放在info relication中的master_repl_offset中。
- slave每秒上报自身offset给master,master也会保存slave的offset。slave接收master发送的命令后,会累加自身的offset,存放在info relication中的slave_repl_offset中
复制积压缓冲区:
保存在主节点上的一个固定长度的队列。默认为1MB,当主节点有连接的从节点时被创建。主节点响应写命令时,不但会把命令发送给从节点,还会写入复制积压缓冲区。缓冲区还存储了每个字节对应的offset。由于该队列先进先出,因为保存的是master最近执行的写命令,时间较早的会被挤出缓冲区。
正常情况下redis是如何决定是全量复制还是部分复制:
- 从节点将offset发送给主节点后,主节点根据offset和缓冲区大小决定能否执行部分复制
- 如果offset偏移量之后的数据,仍然都在复制积压缓冲区里,则执行部分复制
- 如果offset偏移量之后的数据已不在复制积压缓冲区中(数据已被挤出),则执行全量复制

服务器运行ID(run id):
每个节点启动时会成唯一识别的run id。主从节点初次复制时,主节点将自己的runid发送给从节点,从节点将这个runid保存起来。当断线重连时,从节点会将这个runid发送给主节点;主节点根据runid判断能否进行部分复制:
- 如果run id与master的一致,则之前同步过,然后通过offset来判断执行什么样的复制
- 如果不一致,则之前没有跟当前master同步过,只能全量复制
无硬盘复制:
- Redis复制的工作原理基于RDB方式的持久化实现的,也就是master在后台保存RDB快照,slave接收到rdb文件并载入,但是这种方式会存在一些问题:
- 当master禁用RDB时,如果执行了复制初始化操作,Redis依然会生成RDB快照,当master下次启动时执行该RDB文件的恢复,但是因为复制发生的时间点不确定,所以恢复的数据可能是任何时间点的。就会造成数据出现问题
- 当硬盘性能比较慢的情况下(网络硬盘),那初始化复制过程会对性能产生影响
- 2.8.18以后的版本,Redis引入了无硬盘复制选项,可以不需要通过RDB文件去同步,直接发送数据,通过以下配置来开启该功能,在内存中直接创建rdb,然后发送给slave,不在自己本地落地磁盘
本文来自博客园,作者:难得,转载请注明原文链接:https://www.cnblogs.com/zhangbLearn/p/18829280

浙公网安备 33010602011771号