Redis(七)–Redis的复制原理
这篇博客主要包括的内容:
- 1.关于复制:
- 复制是什么?
- 能干嘛?
- 怎么用?
- 复制的缺点
- 2.主从复制:
- 概述
- 面临的问题
- 解决方法
- 什么是主从复制
- 主从复制的作用
- 主从复制的启用
- 主从复制的原理
- 3.全量复制与部分复制
- 4.主从复制常见问题:
- 配置不一致
- 规避全量复制
- 规避复制风暴
- 5.redis的同步机制了解吗?
- 6.读写分离模型了解吗?
一、关于复制?
1.复制是什么?
行话:也就是我们所说的主从复制,主机数据更新后根据配置和策略,自动同步到备机的master/slave机制,master以写为主,slave以读为主。(读写分离)。
2.能干嘛?
- 读写分离
- 容灾恢复
3.怎么用?
-
1)配从库不配主库(跟着主机即可)
从库配置:
-
2)slaveof 主库IP 主库端口
-
每次与master断开后,都需要重新连接,除非你配置进redis.conf文件
-
Info reputation
-
-
3)修改配置文件细节操作:
-
拷贝多个redis.conf文件
-
开启daemonize yes
-
Pid文件名字
-
指定端口
-
Log文件名字
-
Dump.rdb名字
-
-
4)常用3招:
-
一主二仆:主机死了,两个备机原地待命(从机死了,启动后,需要重新连接)
-
薪火相传:
- 上一个slave可以是下一个slave的master,slave同样可以接受其他的slave的链接和同步请求,则该slave作为了链条中下一个的master,可以有效减轻master的写压力
- 中途变更转向:会清除之前的数据,重新建立拷贝最新的slaveof 新主库IP 新主库端口
-
反客为主:原一主二仆中,当主挂了以后,从这2个仆中选一个当主,其中一个仆只需要执行slave no
one,这个就成了master,则原另一个仆可以换成这个为新的主。 当原来的回来以后,还是master,但是现在是两条线了:一个是原master一条,原2仆成一条(变成一主一仆)
-
alsveof no one:使当前数据库停止与其他数据库的同步,转为主数据库。
4.复制的缺点:
复制延时:由于所有的写操作都是先在master上操作,然后同步更新到slave上,所以从master同步到slave机器上有一定的延时,当系统很繁忙时,延时可能会更加严重,slave机器量的增加也会使这个问题更加严重。
二、主从复制
1.概述:
在现有企业中80%公司大部分使用的是redis单机服务,在实际的场景当中单一节点的redis容易面临风险。
2.面临问题:
机器故障。我们部署到一台 Redis 服务器,当发生机器故障时,需要迁移到另外一台服务器并且要保证数据是同步的。而数据是最重要的,如果你不在乎,基本上也就不会使用 Redis 了。
容量瓶颈。当我们有需求需要扩容 Redis 内存时,从 16G 的内存升到 64G,单机肯定是满足不了。当然,你可以重新买个 128G 的新机器。
3.解决办法:
要实现分布式数据库的更大的存储容量和承受高并发访问量,我们会将原来集中式数据库的数据分别存储到其他多个网络节点上。
Redis 为了解决这个单一节点的问题,=也会把数据复制多个副本部署到其他节点上进行复制,实现 Redis的高可用,实现对数据的冗余备份,从而保证数据和服务的高可用。
4.什么是主从复制:
主从复制,是指将一台Redis服务器的数据,复制到其他的Redis服务器。前者称为主节点(master),后者称为从节点(slave),数据的复制是单向的,只能由主节点到从节点。
默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。
一主一从:
一主多从:
5.主从复制的作用:
- 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。
- 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复;实际上是一种服务的冗余。
- 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点),分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
- 读写分离:可以用于实现读写分离,主库写、从库读,读写分离不仅可以提高服务器的负载能力,同时可根据需求的变化,改变从库的数量;
- 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。
6.主从复制启用:
从节点开启主从复制,有3种方式:
- 配置文件: 在从服务器的配置文件中加入:slaveof
- 启动命令: redis-server启动命令后加入 –
- 客户端命令: Redis服务器启动后,直接通过客户端执行命令:slaveof 。,则该Redis实例成为从节点。
通过 info replication 命令可以看到复制的一些信息
7.主从复制原理:
主从复制过程大体可以分为3个阶段:连接建立阶段(即准备阶段)、数据同步阶段、命令传播阶段。
在**从节点执行 slaveof 命令后,复制过程便开始运作**,下面图示大概可以看到,从图中可以看出复制过程大致分为6个过程:
主从配置之后的日志记录也可以看出这个流程:
1)保存主节点(master)信息。
执行 slaveof 后 Redis 会打印如下日志:
2)从节点(slave)内部通过每秒运行的定时任务维护复制相关逻辑,当定时任务发现存在新的主节点后,会尝试与该节点建立网络连接
从节点与主节点建立网络连接
从节点会建立一个 socket 套接字,从节点建立了一个端口为51234的套接字,专门用于接受主节点发送的复制命令。从节点连接成功后打印如下日志:
如果从节点无法建立连接,定时任务会无限重试直到连接成功或者执行 slaveof no one 取消复制
关于连接失败,可以在从节点执行 info replication 查看 master_link_down_since_seconds 指标,它会记录与主节点连接失败的系统时间。从节点连接主节点失败时也会每秒打印如下日志,方便发现问题:
# Error condition on socket for SYNC: {socket_error_reason}
3)发送 ping 命令。
连接建立成功后从节点发送 ping 请求进行首次通信,ping 请求主要目的如下:
- 检测主从之间网络套接字是否可用。
- 检测主节点当前是否可接受处理命令。
如果发送 ping 命令后,从节点没有收到主节点的 pong 回复或者超时,比如网络超时或者主节点正在阻塞无法响应命令,从节点会断开复制连接,下次定时任务会发起重连。
从节点发送的 ping 命令成功返回,Redis 打印如下日志,并继续后续复制流程:
4)权限验证
如果主节点设置了 requirepass 参数,则需要密码验证,从节点必须配置 masterauth 参数保证与主节点相同的密码才能通过验证;如果验证失败复制将终止,从节点重新发起复制流程。
5)同步数据集
主从复制连接正常通信后,对于首次建立复制的场景,主节点会把持有的数据**全部发送给从节点**,这部分操作是耗时最长的步骤。
6)命令持续复制
当主节点把当前的数据同步给从节点后,便完成了复制的建立流程。接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。
三、全量复制和部分复制
runid和复制偏移量:
每个redis在启动的时候都会有一个随机地runid,来表示redis的标志
1、全量复制:
全量复制过程:
- 【步骤一】如果设置了一个Slave,无论是第一次连接还是重连到Master,它都会发出一个PSYNC命令‘
- 【步骤二】当Master收到SYNC命令后,会做两个事情: Master执行BGSAVE,即在后台保存数据到磁盘(RDB快照文件) Master同时将新收到的写入和修改数据集的命令存入缓冲区(非查询类)
- 【步骤三】当Master在后台把数据保存到快照文件完成之后,Master会把这个快照文件传送给Slave,而Slave则把内存清空后,加载该文件到内存中
- 【步骤四】而Master/Slave此后会不断通过异步的方式进行命令的同步,达到最终的数据同步一致
先将RDB文件同步给slave,然后在同步RDB期间,再有向master中写入的数据就单独记录下来,然后当RDB复制完后,观察master和slave的偏移量。
在全量复制的时候,如果发生了网络抖动,那么连接可能会发生断开。
2.部分复制的过程:
- 【步骤一】当Master和Slave之间的连接断开之后,他们之间可以采用持续复制处理方式代替采用全量同步
- 【步骤二】Master端为复制流维护一个内存缓冲区,记录最近发送的复制流命令;同时,Master和Slave之间都维护一个复制偏移量(replication offset)和当前Master服务器ID(Master run id)。当网络断开,Slave尝试重连时:
- 如果MasterID相同(即仍是断网前的Master服务器),并且从断开时到当前时刻的历史命令依然在Master的内存缓存区中存在,则Master会将缺失的这段时间的所有命令发送给Slave执行,然后复制工作就可以继续执行了。
- 否则,依然需要全量复制操作。
四、主从复制常见问题:
- 读写分离:读流量分摊到从节点
- 可能遇到问题
- 复制数据延迟
- 读到过期数据
- 从节点故障
3.2 配置不一致
例如maxmemory不一致:丢失数据
3.3 规避全量复制:
- 第一次全量复制
- 第一次不可避免
- 小主节点:即maxmemory不要设置的过大。低峰:在用户比较 少的时候,比如夜间
- 节点运行ID不匹配
- 主节点重启(运行runID变化)
- 采取措施:故障转移,例如哨兵或者集群
- 复制积压缓冲区不足
- 网络中断,部分复制无法满足
- 采取措施:增大复制缓冲区配置:rel_backlog_size,网络“增强”。
3.4 规避复制风暴
当master连接了很多slave的时候,master宕机了,这个时候所有的slave都需要重新全量复制。
- 单主节点复制风暴:
- 问题:主节点重启,多从节点复制
- 解决:更换复制拓扑
可以更改为右边的架构,但是还是有一个问题,当slave1出现问题了,那么怎么解决。
- 单机器复制风暴
- 机器宕机后,大量全量复制
补:两道题:
redis的同步机制了解吗?
答:当客户端向从服务器发送slaveof命令,要求从服务器复制主服务器时,从服务器首先需要执行同步操作,也就是,将从服务器的数据库状态更新至主服务器当前所处的数据库状态。
从服务器对主服务器的同步操作需要通过向主服务器发送SYNC命令来完成,以下是SYNC命令的执行步骤:
- 从服务器向主服务器发送SYNC命令
- 收到SYNC命令的主服务器执行basave命令,在后台生成一个rdb文件,并使用一个缓冲区记录从现在开始执行的所有写命令
- 当主服务器的bgsave命令执行完毕以后,主服务器会将bgsave命令生成的rdb文件发送给从服务器,从服务器接受并载入这个rdb文件,将自己的数据库状态更新至主服务器执行bgsave命令时的数据库状态
- 主服务器记录在缓冲区里面的所有的写命令发送给从服务器,从服务器执行这些写命令,将自己的数据库状态更新至主服务器数据库当前所处的状态。
读写分离模型了解吗?
读写分离模型的实质也就是复制的原理。也就是说的主从复制,主服务器更新后,根据配置和策略,自动同步到备机的master/slave机制,master以写为主,slave以读为主。这样就做到了读写分离。
读写分离架构的缺陷:不管是master还是slave,每个节点都必保存完整的数据,若在数据量很大的时候,集群的扩展能力还是受限于单个节点的存储能力,而且对于write-intensive模型的应用,读写分离结构并不合适。
感谢并参考:
java知音
https://blog.csdn.net/xiaojie_570/article/details/86475675