Redis 主从复制详解

Redis 主从复制详解

1、主从复制的概念

1.1 什么是主从复制

主从复制是指将一台Redis服务器的数据,复制到其它的Redis服务器。前者称为主节点(master),后者称为从节点(slave);数据的复制是单向的,只能由主节点到从节点

默认情况下,每台Redis服务器都是主节点,且一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。

2.2 主从复制的作用

(1)负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载;尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量。

(2)故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复,但实际上是一种服务的冗余。

(3) 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式

(4)高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础。

2、配置方式

在这里,主要是在centos7.0 上同时启动三个redis进行读写分离的演示

主要分三步:

(1)进入redis 安装目录,分别复制三份redis.6379conf 、redis.6380conf 、redis.6381conf

如下:

[root@localhost redis-4.0.8]# ls
00-RELEASENOTES  CONTRIBUTING  Makefile        redis.6381conf    sentinel.conf
6379.log         COPYING       MANIFESTO       redis.conf        src
6380.log         deps          README.md       runtest           tests
6381.log         dump.rdb      redis.6379conf  runtest-cluster   utils
BUGS             INSTALL       redis.6380conf  runtest-sentinel

(2)修改配置文件
进入redis.6379conf 文件,加入以下配置

port 6379
pidfile /var/run/redis_6379.pid
logfile "6379.log"
dbfilename dump6379.rdb
appendfilename "appendonly6379.aof"

其他两个分别同样修改配置文件

(3)分别启动三个redis客户端,便可以根据需求配置主从关系了。

几个常用的命令:
slaveof [ip地址] [端口号] // 为从服务器配置主服务器
info replication //查看当前服务器的详细信息

3、主从复制的实现原理

Redis的主从复制过程大体上分3个阶段:建立连接、数据同步、命令传播。

3.1 建立连接

这个阶段主要是从服务器发出slaveof命令之后,与主服务器如何建立连接,为数据同步做准备的过程

(1)在slaveof命令执行之后,从服务器根据设置的master的ip地址和端口,创建连向主服务器的socket套接字连接,连接成功后,从服务器会为这个套接字关联一个专门的处理器,用于处理后续的复制工作

(2)建立连接之后,从服务器会向主服务器发送ping命令,确认主服务器是否可用,以及当前是否可用接受处理命令。如果收到主服务器的pong回复说明是可用的,否则有可能是网络超时或主服务器阻塞,从服务器会断开连接发起重连

(3)身份验证。如果主服务器设置了requirepass选项,那么从服务器必须配置masterauth选项,且保证密码一致才能通过验证

(4)身份验证完成之后,从服务器会发送自己的监听端口,主服务器会保存下来

3.2 数据同步

在主从服务器建立连接确认各自身份之后,就开始数据同步,从服务器向主服务器发送PSYNC命令,执行同步操作,并把自己的数据库状态更新至主服务器的数据库状态

Redis的主从同步分为:全量复制(full resynchronization)和增量复制(partial resynchronization)

1、全量复制

发生在Slave初始化阶段,这时slave需要将master上的所有数据都复制一份。步骤如下:

(1)从服务器连接主服务器,发送psync命令;
(2)主服务器接收到SYNC命名后,开始执行BGSAVE命令生成RDB文件并使用缓冲区记录此后执行的所有写命令;
(3)主服务器BGSAVE执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
(4)从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
(5)主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
(6)从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

在这里插入图片描述

2、增量复制

增量是用于处理断线后重复制的情况,先介绍几个用于增量的部分

(1)runid(replication ID),主服务器运行id,Redis实例在启动时,随机生成一个长度40的唯一字符串来标识当前节点;

(2)offset,复制偏移量。主服务器和从服务器各自维护一个复制偏移量,记录传输的字节数。当主节点向从节点发送N个字节数据时,主节点的offset增加N,从节点收到主节点传来的N个字节数据时,从节点的offset增加N

(3)replication backlog buffer,复制积压缓冲区。是一个固定长度的FIFO队列,大小由配置参数repl-backlog-size指定,默认大小1MB。需要注意的是该缓冲区由master维护并且有且只有一个,所有slave共享此缓冲区,其作用在于备份最近主库发送给从库的数据。


大致过程如下:

(1)当slave重连连接到master,会执行PSYNC 发送记录旧的master的runid(replication ID)和偏移量offset,这样master能够只发送slave所缺的增量部分。

(2)但是如果master的复制积压缓存区没有足够的命令记录,或者slave传的runid(replication ID)不对,就会进行全量,即slave会获得一个完整的数据集副本

大致流程如下:

在这里插入图片描述

3.3 命令传播

当完成数据同步之后,主从服务器的数据暂时达到一致状态,当主服务器执行了客户端的写命令之后,主从的数据便不再一致。为了能够使主从服务器的数据保持一致性,主服务器会对从服务器执行命令传播操作,即每执行一个写命令就会向从服务器发送同样的写命令

在命令传播阶段,从服务器会默认以每秒一次的频率向主服务器发送心跳检测REPLCONF ACK <replication_offset>其中replication_offset是当前从服务器的复制偏移量

该命令的作用有三个
(1)检测主从服务器的网络连接状态
(2)辅助实现min-slaves选项
(3)检测命令丢失

4、哨兵模式

4.1 为什么需要哨兵机制

有了主从复制的实现以后,如果想对主服务器进行监控,那么在redis2.6以后提供了一个"哨兵"的机制。顾名思义,哨兵的含义就是监控redis系统的运行状态。可以启动多个哨兵,去监控redis数据库的运行状态。其主要功能有两点:

(1)监控所有节点数据库是否在正常运行

(2)master数据库出现故障时,可以自动通过投票机制,从slave节点中选举新的master,实现将从数据库转换为主数据库的自动切换



  一个一主多从的Redis系统中,可以使用多个哨兵进行监控任务以保证系统足够稳健。此时,不仅哨兵会同时监控主数据库和从数据库,哨兵之间也会相互监控。在这里,建议大家哨兵至少部署3个,并且使用奇数个哨兵

Redis的哨兵(sentinel) 系统用于管理多个 Redis 服务器,该系统执行以下三个任务:

(1)监控(Monitoring): 哨兵(sentinel) 会不断地检查你的Master和Slave是否运作正常。
(2)提醒(Notification):当被监控的某个 Redis出现问题时, 哨兵(sentinel) 可以通过 API 向管理员或者其他应用程序发送通知。
(3)自动故障迁移(Automatic failover):当一个Master不能正常工作时,哨兵(sentinel) 会开始一次自动故障迁移操作,它会将失效Master的其中一个Slave升级为新的Master, 并让失效Master的其他Slave改为复制新的Master; 当客户端试图连接失效的Master时,集群也会向客户端返回新Master的地址,使得集群可以使用Master代替失效Master。

4.2 哨兵机制的原理

哨兵(sentinel) 是一个分布式系统,你可以在一个架构中运行多个哨兵(sentinel) 进程,这些进程使用流言协议(gossipprotocols)来接收关于Master是否下线的信息,并使用投票协议(agreement protocols)来决定是否执行自动故障迁移,以及选择哪个Slave作为新的Master.
  每个哨兵(sentinel) 会向其它哨兵(sentinel)、master、slave定时发送消息,以确认对方是否”活”着,如果发现对方在指定时间(可配置)内未回应,则暂时认为对方已挂(所谓的”主观认为宕机” Subjective Down,简称sdown).
若“哨兵群”中的多数sentinel,都报告某一master没响应,系统才认为该master"彻底死亡"(即:客观上的真正down机,Objective Down,简称odown),通过一定的vote算法,从剩下的slave节点中,选一台提升为master,然后自动修改相关配置.
  虽然哨兵(sentinel) 释出为一个单独的可执行文件 redis-sentinel ,但实际上它只是一个运行在特殊模式下的 Redis 服务器,你可以在启动一个普通 Redis 服务器时通过给定 --sentinel 选项来启动哨兵(sentinel).
哨兵(sentinel) 的一些设计思路和zookeeper非常类似

1、监控
sentinel会每秒一次的频率与之前创建了命令连接的实例发送PING,包括主服务器、从服务器和sentinel实例,以此来判断当前实例的状态。down-after-milliseconds时间内PING连接无效,则将该实例视为主观下线。之后该sentinel会向其他监控同一主服务器的sentinel实例询问是否也将该服务器视为主观下线状态,当超过某quorum后将其视为客观下线状态。

当一个主服务器被某sentinel视为客观下线状态后,该sentinel会与其他sentinel协商选出零头sentinel进行故障转移工作。每个发现主服务器进入客观下线的sentinel都可以要求其他sentinel选自己为领头sentinel,选举是先到先得。同时每个sentinel每次选举都会自增配置纪元,每个纪元中只会选择一个领头sentinel。如果所有超过一半的sentinel选举某sentinel领头sentinel。之后该sentinel进行故障转移操作。

如果一个Sentinel为了指定的主服务器故障转移而投票给另一个Sentinel,将会等待一段时间后试图再次故障转移这台主服务器。如果该次失败另一个将尝试,Redis Sentinel保证第一个活性(liveness)属性,如果大多数Sentinel能够对话,如果主服务器下线,最后只会有一个被授权来故障转移。 同时Redis Sentinel也保证安全(safety)属性,每个Sentinel将会使用不同的配置纪元来故障转移同一台主服务器。

2、故障转移

(1)首先是从主服务器的从服务器中选出一个从服务器作为新的主服务器。选点的依据依次是:网络连接正常->5秒内回复过INFO命令->10*down-after-milliseconds内与主连接过的->从服务器优先级->复制偏移量->运行id较小的。选出之后通过slaveif no ont将该从服务器升为新主服务器。

(2)通过slaveof ip port命令让其他从服务器复制该信主服务器

(3)最后当旧主重新连接后将其变为新主的从服务器。注意如果客户端与就主服务器分隔在一起,写入的数据在恢复后由于旧主会复制新主的数据会造成数据丢失。

故障转移成功后会通过发布订阅连接广播新的配置信息,其他sentinel收到后依据配置纪元更大来更新主服务器信息。Sentinel保证第二个活性属性:一个可以相互通信的Sentinel集合会统一到一个拥有更高版本号的相同配置上。
在这里插入图片描述
在这里插入图片描述

哨兵机制是有缺点的:

(1)主从服务器的数据要经常进行主从复制,这样造成性能下降。

(2)当主服务器宕机后,从服务器切换成主服务器的那段时间,服务是不能用的。



参考:
https://www.cnblogs.com/huangfuyuan/p/9880379.html
https://baijiahao.baidu.com/s?id=1644916874411447363&wfr=spider&for=pc

发布了78 篇原创文章 · 获赞 53 · 访问量 8171

猜你喜欢

转载自blog.csdn.net/qqq3117004957/article/details/104787087