redis高可用:主从复制、哨兵模式

主从复制

概述

主从复制有如下特点:一个master可以拥有多个slave,但是一个slave只能对应一个master;

  • 负载均衡:主数据库可以进行读写操作,当读写操作导致数据变化时会自动将数据同步给从数据库;从数据库一般是只读的,并且接收主数据库同步过来的数据;
  • 故障恢复:slave挂了不影响其他slave的读和master的读和写,重新启动后会将数据从master同步过来;
    • master挂了以后,不影响slave的读,但redis不再提供写服务,master重启后redis将重新对外提供写服务;
    • master挂了以后,不会在slave节点中重新选一个master
  • 高可用基石:除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础

主从库之间采用的是读写分离的方式。

  • 读操作:主库、从库都可以接收

    主节点(Master):唯一可写节点,处理所有写操作

  • 写操作:首先到主库执行,然后,主库将写操作同步给从库

    从节点(Slave):只读副本,通过复制流同步主节点数据

复制流程

1.建立复制关系

从节点执行命令:

SLAVEOF <master_ip> <master_port>  # 建立主从关系  

连接建立过程:

  1. 从节点向主节点发送PING确认连通性
  2. 主节点响应PONG
  3. 从节点发送REPLCONF listening-port 声明自身端口

2. 全量同步(Full Resynchronization)

触发条件

从节点首次连接主节点

  1. 发送 psync 命令进行数据同步,由于是第一次进行复制,从节点没有复制偏移量和主节点的运行ID,所以发送 psync-1;
  2. 主节点根据 psync-1 解析出当前为全量复制,回复 +FULLRESYNC 响应;
  3. 从节点接收主节点的响应数据保存运行 ID 和偏移量 offset;

主从复制ID不匹配(主节点发生过故障切换)

执行步骤:
  1. 主节点执行bgsave生成RDB快照
  2. 主节点将RDB文件发送给从节点,从节点把接收的 RDB 文件保存在本地并直接作为从节点的数据文件;

    主库将数据同步给从库的过程中,主库不会被阻塞,仍然可以正常接收请求

  3. 从节点清空旧数据,从节点清空数据后加载RDB文件

    为了避免之前数据的影响,从库需要先把当前数据库清空

  4. 主节点将RDB生成期间的写命令存入复制缓冲区(Replication Buffer)

    为了保证主从库的数据一致性,主库会在内存中用专门的 replication buffer,记录 RDB 文件生成后收到的所有写操作

  5. RDB加载完成后,主节点发送缓冲区中的增量命令

    当主库完成 RDB 文件发送后,就会把此时 replication buffer 中的修改操作发给从库,从库再重新执行这些操作。这样一来,主从库就实现同步了。

Redis 为什么主从全量复制使用RDB而不使用AOF

RDB文件内容是经过压缩的二进制数据(不同数据类型数据做了针对性优化),文件很小。

从库在加载RDB文件时,一是文件小,读取整个文件的速度会很快,二是因为RDB文件存储的都是二进制数据,从库直接按照RDB协议解析还原数据即可,速度会非常快

AOF文件记录的是每一次写操作的命令,写操作越多文件会变得很大,其中还包括很多对同一个key的多次冗余操作。

AOF需要依次重放每个写命令,这个过程会经历冗长的处理逻辑,恢复速度相比RDB会慢得多,所以使用RDB进行主从全量复制的成本最低

另外就是RDB操作简单

假设要使用AOF做全量复制,意味着必须打开AOF功能,打开AOF就要选择文件刷盘的策略,选择不当会严重影响Redis性能
而RDB只有在需要定时备份和主从全量复制数据时才会触发生成一次快照。
而在很多丢失数据不敏感的业务场景,其实是不需要开启AOF的。

3. 增量同步

增量同步(Partial Resynchronization):如果主从库在命令传播时出现了网络闪断,那么,从库就会和主库重新进行一次全量复制,开销非常大从 Redis 2.8 开始,网络断了之后,主从库会采用增量复制的方式继续同步

触发条件

网络闪断后重连

  1. 当主从节点之间网络出现中断时,如果超过 repl-timeout 时间,主节点会认为从节点故障并中断复制连接;
  2. 主从连接中断期间主节点依然响应命令,但因复制连接中断命令无法发送给从节点,不过主节点内部存在的复制积压缓冲区,依然可以保存最近一段时间的写命令数据,默认最大缓存 1MB;
  3. 当主从节点网络恢复后,从节点会再次连上主节点;

从节点的复制偏移量(offset)仍在主节点缓冲区范围内

执行机制
  1. 从节点发送PSYNC

    当主从连接恢复后,由于从节点之前保存了自身已复制的偏移量和主节点的运行 ID。因此会把它们当作 psync 参数发送给主节点,要求进行部分复制操作

  2. 主节点验证复制ID和offset有效性

    主节点接到 psync 命令后首先核对参数 runId 是否与自身一致,如果一致,说明之前复制的是当前主节点;
    根据参数 offset 在自身复制积压缓冲区查找,如果偏移量之后的数据存在缓冲区中,则对从节点发送 +CONTINUE 响应,表示可以进行部分复制;

  3. 有效时发送+CONTINUE并传输缺失的增量数据

    主节点根据偏移量把复制积压缓冲区里的数据发送给从节点,保证主从复制进入正常状态

实现

在这里说明一下核心步骤,具体的实现步骤可上网再自行搜索
配置步骤

  1. 主节点配置(无需特殊配置):打开master节点文件,文件位于vi/usr/local/redis/redis.conf目录下,然后修改配置如下:
bind 0.0.0.0      # 允许远程连接
masterauth 123456               # slave连接master密码,master可省略
requirepass 123456              # 设置master连接密码,slave可省略
  1. 从节点配置:
#  replicaof用于追随某个节点的redis,被追随的节点为主节点,追随的为从节点。就是设置master节点
replicaof 192.168.1.100 6379 # 指定主节点信息
masterauth 123456  # 主节点密码(如果设置了认证)

# 优化配置
repl-diskless-sync yes       # 无盘复制(适用于磁盘性能差的环境)
repl-diskless-sync-delay 5   # 无盘复制等待时间(秒)
  1. 验证:查看节点状态
# 启动redis
systemctl start redis
systemctl status redis

# 查看集群的一些数据:
# 交互式
redis-cli -h 192.168.1.110 -a 123456
192.168.182.110:6379> info replication

# 交互式
redis-cli -h 192.168.1.110
192.168.182.110:6379> auth 123456
192.168.182.110:6379> info replication

# 非交互式
redis-cli -h 192.168.1.110 -a 123456 info replication

/* 输出如下
# Replication
role:master
connected_slaves:2
slave0:ip=192.168.1.101,port=6379,state=online,offset=123456,lag=0
slave1:ip=192.168.1.102,port=6379,state=online,offset=123456,lag=1
*/

哨兵模式

概述

主从模式的弊端就是不具备高可用性,当master挂掉以后,Redis将不能再对外提供写入操作,因此sentinel模式应运而生

Redis 哨兵模式(Sentinel)是实现高可用的核心方案,专为解决主从架构中的 自动故障转移 和 服务发现 问题而设计

主从复制 vs 哨兵模式

特性主从复制哨兵模式
自动故障转移不支持支持
高可用保障需手动干预自动切换
复杂度简单需维护 Sentinel
适用场景数据备份/读写分离生产环境高可用需求

流程

监控
监控
监控
Sentinel-1
Master
Sentinel-2
Sentinel-3

在这里插入图片描述

核心功能

  1. 节点监控:持续检测主/从节点健康状态
  2. 自动故障转移:主节点故障时选举新主节点
  3. 配置中心:向客户端提供最新的主节点地址
  4. 通知告警:通过API或脚本触发告警

原理

pub/sub 机制

哨兵实例之间可以相互发现,要归功于 Redis 提供的 pub/sub 机制,也就是发布 / 订阅机制。

redis:redis Module 、 redis应用、Redis事件机制、redis Stream

  • 在主从集群中,主库上有一个名为sentinel:hello的频道,不同哨兵就是通过它来相互发现,实现互相通信的
    1. 哨兵 1 把自己的 IP(172.16.19.3)和端口(26579)发布到sentinel:hello频道上,哨兵 2 和 3 订阅了该频道
    2. 哨兵 2 和 3 就可以从这个频道直接获取哨兵 1 的 IP 地址和端口号
    3. 如此,哨兵 2、3 可以和哨兵 1 建立网络连接,哨兵 2 和 3 也可以建立网络连接。它们相互间可以通过网络连接进行通信,比如说对主库有没有下线这件事儿进行判断和协商。
  • 哨兵监控:哨兵向主库发送 INFO 命令来完成的。如下图所示
    1. 哨兵 2 给主库发送 INFO 命令,主库接受到这个命令后,就会把从库列表返回给哨兵。
    2. 哨兵就可以根据从库列表中的连接信息,和每个从库建立连接,并在这个连接上持续地对从库进行监控。
    3. 哨兵 1 和 3 可以通过相同的方法和从库建立连接。

判断主库已经下线

哨兵如何判断主库已经下线:两种概念,主观下线和客观下线

  • 主观下线:任何一个哨兵都是可以监控探测,并作出Redis节点下线的判断

    当某个哨兵(如下图中的哨兵2)判断主库“主观下线”后,就会给其他哨兵发送 is-master-down-by-addr 命令,其他哨兵会根据自己和主库的连接情况,做出 Y 或 N 的响应,Y 相当于赞成票,N 相当于反对票。

  • 客观下线:由哨兵集群共同决定Redis节点是否下线

    如果赞成票数是大于等于哨兵配置文件中的 quorum 配置项, 则可以判定主库客观下线了

在这里插入图片描述

哨兵集群的选举

选举的作用:由哪个哨兵节点来执行主从切换

为什么需要选举

  • 为了避免哨兵的单点情况发生,所以需要一个哨兵的分布式集群
  • 分布式集群,必然涉及共识问题(即选举问题)
  • 同时故障的转移和通知都只需要一个主的哨兵节点就可以了

哨兵的选举机制:Raft选举算法

选举的票数大于等于num(sentinels)/2+1时,将成为领导者,如果没有超过,继续选举

任何一个想成为 Leader 的哨兵,要满足两个条件:

  • 第一,拿到半数以上的赞成票;
  • 第二,拿到的票数同时还需要大于等于哨兵配置文件中的 quorum 值。

    以 3 个哨兵为例,假设此时的 quorum 设置为 2,那么,任何一个想成为 Leader 的哨兵只要拿到 2 张赞成票,就可以

分布式算法(待补充链接)

分布式算法:Paxos 、Zab、Raft、一致性hash

新主库的选出

选择新的主库,有下面三个选择条件,依顺序去筛选

  1. 选择健康节点:过滤掉不健康的(下线或断线),没有回复过哨兵ping响应的从节点
  2. 选择优先级高的节点:选择salve-priority从节点优先级最高(redis.conf)的
  3. 选择尽量完整节点:选择复制偏移量最大,只复制最完整的从节点

故障的转移

基本概念

判断主库客观下线了,同时选出sentinel 3是哨兵leader,故障转移流程如下:

  1. 将slave-1脱离原从节点,升级主节点,
  2. 将从节点slave-2指向新的主节点slave-1
  3. 通知客户端主节点已更换
  4. 将原主节点(oldMaster)变成从节点,指向新的主节点
  5. 转移后,slave-1新主节点有两个副本slave-2和old master,而old master不再有副本,哨兵集群仍然监控所有的主从节点
流程总结

对上述的判断到转移做一个总结

工作的流程如下所示:

  1. 每个sentinel以每秒钟一次的频率向它所知的master,slave以及其他sentinel实例发送一个 PING 命令;

  2. 如果一个实例距离最后一次有效回复 PING 命令的时间超过 down-after-milliseconds 选项所指定的值, 则这个实例会被sentinel标记为主观下线

  3. 如果一个master被标记为主观下线,则正在监视这个master的所有sentinel要以每秒一次的频率确认master的确进入了主观下线状态;

  4. 当有足够数量的sentinel(大于等于配置文件指定的值)在指定的时间范围内确认master的确进入了主观下线状态, 则master会被标记为客观下线

    在一般情况下, 每个sentinel会以每 10 秒一次的频率向它已知的所有master,slave发送 INFO 命令;
    当master被sentinel标记为客观下线时,sentinel向下线的master的所有slave发送 INFO 命令的频率会从 10 秒一次改为 1 秒一次;

  5. 若没有足够数量的sentinel同意master已经下线,master的客观下线状态就会被移除;若master重新向sentinel的 PING 命令返回有效回复,master的主观下线状态就会被移除。

配置哨兵模式

哨兵模式是基于主从模式的
我们只需要在主从模式的基础上直接修改sentinel配置文件,哨兵的配置主要就是修改sentinel.conf配置文件中的参数,在Redis安装目录即可看到此配置文件,主要参数如下:

参数作用
sentinel monitor <name> <ip> <port> <quorum>定义监控的主节点和法定人数(同意故障转移的哨兵数)
down-after-milliseconds主节点无响应多久后标记为主观下线(单位:毫秒)
failover-timeout故障转移超时时间,超时后终止转移
parallel-syncs故障转移后,同时从新主节点同步数据的从节点数(避免带宽拥塞)

配置如下

//端口默认为26379。
port:26379
//关闭保护模式,可以外部访问。
protected-mode:no
//设置为后台启动。
daemonize:yes
//日志文件。
logfile:./sentinel.log
//指定主机IP地址和端口,并且指定当有2台哨兵认为主机挂了,则对主机进行容灾切换。
sentinel monitor mymaster 192.168.231.130 6379 2
//当在Redis实例中开启了requirepass,这里就需要提供密码。
sentinel auth-pass mymaster pwdtest@2019
//判断master主观下线时间,默认30s
sentinel down-after-milliseconds mymaster 3000
//主备切换时,最多有多少个slave同时对新的master进行同步,这里设置为默认的1。
sentinel parallel-syncs mymaster 1
//故障转移的超时时间,这里设置为三分钟。
sentinel failover-timeout mymaster 180000

启动sentinel模式的命令如下:

/usr/local/bin/redis-sentinel /usr/local/redis/sentinel.conf

验证哨兵状态

redis-cli -p 26379 sentinel masters
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

?abc!

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

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

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

打赏作者

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

抵扣说明:

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

余额充值