redis主从复制

前言

本篇笔者来总结一下对redis主从复制学习,如果本篇有任何错误请帮忙指出。


`提示:写博客是自己对知识梳理,目前是写给自己看,算是自己学习后的作业,也是为了养成一个良好的习惯。

一、主从复制概述

1.定义

	主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点。
	其中每个master节点可以有多个slave节点,但是每个slave节点只能有一个master节点。

2.作用

1. 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
2. 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
3. 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写3. Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
4. 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

二、主从复制原理

1.主从复制工作原理

工作原理如下:
	1、slave向master发起同步请求,slave会告知master自己的offset,如果是第一次,offset=-1表示需要全量同步;
	2、slave连上了master,master会给slave分配一个client buffer(复制缓冲区);
	3、master fork子进程dump RDB文件,dump完成后告诉父进程,父进程把RDB发给slave(通过slave的socket发过去);
	4、slave载入rdb到本地磁盘;
	5、在master dump RDB期间,master所有写命令,都写到这个client buffer然后同步给slave
	6、slave执行同步过来的buffer命令。
	
	在全量同步时,同步的是RDB,该过程较耗时;在增量同步时,同步的是client buffer
(复制积压缓冲区,也叫replication buffer)数据,该过程比较高效。

可以参考一下我画的图:

在这里插入图片描述

2.全量复制与增量复制

Redis2.8以前,从节点向主节点发送sync命令请求同步数据,此时的同步方式是全量复制;在Redis2.8及以后,从节点可以发送psync命令请求同步数据,此时根据主从节点当前状态的不同,同步方式可能是全量复制或部分复制。后文介绍以Redis2.8及以后版本为例。
	
全量复制场景:
	1. salve第一次会向master请求同步数据时;
	2. 原master挂掉了或脑裂了,重新进入集群中会先删除自己数据,然后向新master请求同步数据时;
	3. 宕机重启的salve重新进入集群时为了保证数据一致性也会先删除自己数据,向master请求同步数据时;
	以上在进行全量数据同步时,传给master的偏移量offset=-1;

增量复制场景:
	用于网络中断等情况后的复制,只将中断期间主节点执行的写命令发送给从节点,与全量复制相比更加高效,
但是如果网络中断的时间超过了阈值,会被认定为其宕机了,之后重新进入集群后还是会走全量数据同步。
	以上在进行增量数据同步时,传给master的偏移量offset>0

3.增量同步实现底层原理

	这里以上我们了解到了主从复制的2个模式,对于全量复制都好理解,那么这里我们剖析一下redis是如何
来实现增量同步的,它主要的核心是repl_backlog_buffer(复制积压缓冲区).

repl_backlog_buffer:(按照以上图来说一下buffer的过程)
	1.在slave在向msater请求数据同步时,master收到请求后都会给salve申请一片内存
(repl_backlog_buffer);
	2. 只要master有写命令进来,也都会写一份到repl_backlog_buffer里,它还存储了其中的每个字
节对应的复制偏移量(offset),但这个buffer是固定大小的环形缓冲区,写满就会覆盖旧数据.
	3. master拿到salve提供的offset来在repl_backlog_buffer找数据看能否接得上,
如果匹配到了数据就将repl_backlog_buffer同步给salve,如果没有匹配到数据就走全量数据同步。

总结就是:
	1. repl_backlog_buffer是为了解决从库断连后找不到主从差异数据而设立的环形缓冲区,从而避免全量同步带来的性能开销;
	2. repl_backlog_size配置大一些可以减少出现全量同步的概率。

3.无盘复制

定义:
	repl-diskless-sync = yes,表示master不会在磁盘生成RDB文件,而是直接把全量数据,
通过socket发给slave,这种也叫无盘复制。

对比:
	RDB全量复制是先生成RDB文件(这个比较耗时),然后有其他salve来请求时,可以直接复用之前的
RDB文件。
	无盘复制不需要生成rdb文件,直接扫描实例内存通过socket传给salve,则有其他salve来请求时,
不能复用需要再次扫描实例内存,当然redis对该问题做了优化,就是开启配置repl-diskless-sync-delay,表示开始给slave传输数据之前,等待一会再发数据给slave,如果此时有其他slave连上来请求全量同步,那么在这等待的期间,就可以兼顾其他slave,减少扫描整个实例的次数,降低同步成本。

3.级联模式

	在一主多从的集群中,多个salve都来请求数据同步,master都会通过socket方式将数据同步给
salve,如果salve过多,就会拉胯master的性能,为了解决这问题redis支持级联模式的主从同步,
即master将数据同步给A salve,然后其他节点可以从 A salve上同步数据,图示如下:

在这里插入图片描述

三、主从复制问题

1.读写分离相关问题

数据延迟和不一致问题:
	由于主从复制的命令传播是异步的,延迟与数据的不一致是不可避免的,只能尽可能减少发生的频率。
	解决优化方案就是:集群尽量用物理机部署在同一个局域网中,减少网络异常的频率;
控制redis实例的大小(建议不要超过6G);主从节点服务内存一致且配置参数一致,尽量减少
由于内存不一致而触发了内存淘汰机制,导致主从数据不一致。

数据过期问题:
	redis过期策略是 惰性删除+定期删除,那么就存在一个这样的问题就是key在master上过期了,
并且也同步给salve上了,由于做了读写分离在salve读取到了这个key,以上场景在redis3.2之前
salve会读到已过期key的数据,在redis3.2之后客户端也会判断key是否过期,如果过期则返回客户端
null值,待master节点淘汰该key之后同步给salve才会删除这个key,以这种方式解决了读写分离下
数据过期问题。

故障切换问题:
	redis主从模式并不支持高可用,当master宕机后,整个集群就瘫痪了,需要人工干预恢复数据,
为了解决这个问题于是就有了高可用的集群模式--哨兵集群。

2.复制超时问题

全量复制 =主节点在fork子进程+保存RDB文件。

网络异常导致超时:
	推荐在同一个局域网中用物理机部署集群,尽可能减少网络异常的频率。
	
实例太大导致超时:
	推荐实例大小不要超过6G,合理配置repl-timeout时间,它值略大于主节点在fork子进程+保存RDB文件
的耗时时间。
	
复制缓冲区溢出导致超时:
	master在全量复制期间的所有写入命令都会写到复制缓冲区中,如果全量复制时间较长且期间写命令较多
就会导致复制缓冲区溢,重新做全量复制,严重时会一直不断的重复这个过程 全量复制--复制缓冲区溢--全量复制。
	方案:1. 全量复制时间尽可能短(控制实例内存大小,采用物理机部署等);2. 合理加大复制缓冲区的大小。

总结

我预计这篇博客只需要花2个小时就可以写完,因为我之前有简单做过笔记,但是实际上我整整花了6个小时,在整理的过程中不断翻书反复查阅资料,在整理完这篇后我对于redis主从复制原理更加深刻了,如果以上内容有任何问题请帮忙指出,谢谢。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ariel小葵

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值