Redis主从复制
[Redis主从复制](replica)是一个多Redis实例进行数据同步的过程,其中一个实例是主实例(Master),其他实例是从实例(Slave)。主实例负责处理命令请求,而从实例则 periodically 地从主实例拉取数据副本。就是当master数据发生变化时,自动将新的数据异步同步到其它slave数据库
作用:
数据冗余:通过主从复制,可以实现数据的热备份,这是持久化之外的一种数据冗余方式,确保数据的安全性。
故障恢复:当主节点出现问题时,可以从节点提供服务,实现快速的故障恢复,从而提高系统的可用性。
负载均衡:在主从复制的基础上,配合读写分离,主节点负责写操作,从节点负责读操作,这样可以分担服务器的负载,尤其是在写操作较少而读操作较多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。
高可用基石:主从复制还是[哨兵]和[集群]能够实施的基础,因此说主从复制是[Redis]高可用的基础
命令 | 描述 |
---|---|
info replication | 可以查看复制节点的主从关系和配置信息 |
replicaof 主库ip 主库端口 | 指定复制哪个主机(一般写入redis.conf配置文件内)。主从复制 |
saveof主库ip 主库端口 | 每次与master断开之后,都需要重新连接,除非配置进reids.conf文件。在运行期间修改slave节点的信息,如果该数据库已经是某个主数据库的从数据库,那么将会定制和原主数据库的同步关系转而和新的主数据库同步,改换门庭。 |
slaveof no one | 使得当前数据库停止与其他数据库的同步。转成主数据库,自立为王 |
一主二仆
方案一:配置文件固定写死(配置文件中,主从关系持久稳定,在从机down后重启不会破坏与主机之间的从属关系)
方案二:命令操作手动指定(命令指定,主从关系只在当次生效,在从机down后重启从机自动恢复为主机状态,与主机之间的从属关系失效)
主从问题
-
从机可以执行写命令码?
从机只有只读权限,不能写入数据。有利于读写分离
-
slave是从头开始复制还是从切入点开始复制?
首次一锅端,后续跟随,master写,slave跟
-
主机shutdown后,从机会上位吗?
从机不动,原地待命,从机数据还可以正常使用,等待主机重启归来
-
主机shutdown后,重启之后主从关系还在吗?
主机重启后仍然是主机,主从关系还存在,并且从机还 是可以顺利进行主从复制
-
某一台从机down后,master继续,从机重启后还能跟上大部队吗?
可以跟随上大部队,将数据誊抄过来
薪火相传
上一个slave可以是下一个slave的master,slave同样可以接收其它slave的连接和同步请求,那么该slave作为了链条中下一个master,可以有效的减轻主master的写压力
中途变更转向,会清除之前的数据,重新建立拷贝最新的数据
反客为主
使当前数据库停止与其它数据库的同步,转换成主数据库(奴隶翻身成主人了)
复制原理与工作流程
1.保存主节点信息:从节点保存主节点的 IP + PORT(IP和端口) 信息。
2.主从建立连接:从节点向主节点发起三次握手,建立 TCP 连接。(在系统层面上验证双方通信信道是否正常)
3.发送 ping 命令:从节点向主节点发送 ping,主节点返回 pong。(在应用层面上验证主节点能够正常工作)
4.权限验证:如果主节点设置了 requirepass 参数,需要进行密码验证。
5.同步数据集:对于首次建立复制的场景,主节点会把当前持有的所有数据全部发送给从节点,即全量同步;对于断开重连的从节点,会根据情况进行全量同步或部分同步。
6.命令持续复制:当从节点复制了主节点的所有数据之后,针对之后的修改命令,主节点会持续的把命令发送给从节点,从节点执行修改命令,保证主从数据的一致性。
PSYNC数据同步
PSYNC(Partial SYNChronization)是Redis复制(Replication)机制中的一种数据同步方式,用于在主从复制场景中高效地同步数据。PSYNC支持全量同步和增量同步两种方式,以确保主从节点之间的数据一致性。
-
全量复制:一般用于初次复制场景,Redis 早期支持的复制功能只有全量复制,它会把主节点全部数据一次性发送给从节点,当数据量较大时,会对主从节点和网络造成很大的开销。
-
部分复制:用于处理在主从复制中因网络闪断等原因造成的数据丢失场景,当从节点再次连上主节点后,如果条件允许,主节点会补发数据给从节点。因为补发的数据远小于全量数据,可以有效避免全量复制的过高开销。
从节点在与主节点建立好主从关系后会自动执行 psync 进行数据同步,不需要我们手动执行。
全量复制流程
-
1.从节点发送 PSYNC 命令给主节点进行数据同步,由于是第一次进行复制,从节点没有主节点的运行 ID 和复制偏移量,所以发送 PSYNC ? -1。
-
2.主节点根据命令,解析出要进行全量复制,回复 +FULLRESYNC 响应。
-
3.从节点接收主节点的运行信息进行保存,包括主节点的 replid 与当前的 offset。
-
4.主节点执行 BGSAVE 进行 RDB 文件的持久化。
-
5.主节点发送 RDB 文件给从节点,从节点保存 RDB 数据到本地硬盘 (全量数据)。
-
6.主节点将 从生成 RDB 到接收完成期间执行的 写命令 写入缓冲区中,等从节点保存完 RDB 文件后,主节点再将缓冲区内的数据补发给从节点,补发的数据仍然按照 RDB 的二进制格式追加写入到收到的 RDB 文件中,保持主从一致性 (增量数据)。
-
7.从节点清空自身原有旧数据。
-
8.从节点加载 RDB 文件得到与主节点一致的数据。
-
9.如果从节点加载 RDB 完成之后,并且开启了 AOF 持久化功能,它会进行 BGREWRITE 操作,得到最近的 AOF 文件
-
部分复制流程
-
1.当主从节点之间出现网络中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并终止复制连接。
-
2.主从连接中断期间主节点依然响应命令,但这些复制命令都因网络中断无法及时发送给从节点,所以暂时将这些命令滞留在复制积压缓冲区 repl-backlog-buffer 中。
-
3.当主从节点网络恢复后,从节点再次连上主节点。
-
4.从节点将之前保存的 replicationId 和复制偏移量作为 PSYNC 的参数发送给主节点,请求进行部分复制。 5.主节点接到 PSYNC 请求后,进行必要的验证。然后根据 offset 去 repl-backlog-buffer 查找合适的数据,并响应 +CONTINUE 给从节点。
-
6.主节点将需要从节点同步的数据发送给从节点,最终完成一致性。
实时复制流程
主从节点在建立复制连接后,会进行实时复制 (实时数据同步)。主节点会把自己收到的修改命令,通过 TCP 长连接的方式,源源不断地传输给从节点 (注意发送的是命令而不是二进制数据)。从节点会根据这些请求来同时修改自身的数据,以保持和主节点数据的一致性。
另外,这样的长连接,需要通过心跳包的方式来维护连接状态:(这里的心跳是指应用层自己实现的心跳,而不是 TCP 自带的心跳)
-
主从节点彼此都有心跳检测机制,各自模拟成对方的客户端进行通信。
-
主节点默认每隔 10 秒对从节点发送 ping 命令,判断从节点的存活性和连接状态。
-
从节点默认每隔 1 秒向主节点发送 replconf ack {offset} 命令,给主节点上报自身当前的复制偏移量。
如果主节点发现从节点通信延迟超过 repl-timeout 配置的值(默认 60 秒),则判定从节点下线,断开复制客户端连接。从节点恢复连接后,心跳机制继续进行。
-
slave启动,同步初请
①slave启动成功连接到master后会发送一个sync命令
②slave首次全新连接到master,一次完全同步(全量复制)将会被自动执行,slave自身原有的数据将会被master数据覆盖清除
首次连接,全量复制
①master节点收到sync命令后会开始在后台保存快照(RDB持久化,主从复制时会触发RDB),同时收集所有接收到的用于修改数据库集命令缓存起来,master节点执行RDB持久化后,master将RDB快照文件和所有缓存的命令发送到所有slave,以完成一次完全同步
②而slave服务在接收到数据库文件数据后,将其存盘并加载到内存中,从而完成复制初始化
心跳持续,保持通信
master继续将新的所有收集到的修改命令自动依次传给slave,完成同步
进入平稳,增量复制
master继续将新的所有收集到的修改命令自动依次传给slave,完成同步
从机下线,重连续传
master会检查backlog里面的offset,master和slave都会保存一个复制的offset还有一个masterid,offset是保存在backlog中的。master只会把已经复制的offset后面的数据复制给slave,类似断点续传
缺点
①复制延时,信号衰减
由于所有的写操作都是先在Master上操作,然后同步更新到Slave上,所以从Master同步到Slave机器有一定的延迟,当系统很繁忙的时候,延迟问题会更加严重,Slave机器数量的增加也会使这个问题更加严重
②主机挂机后,需要手动指定新的主机