Redis-主从集群+主从同步+哨兵机制

Redis面试篇

Redis主从

单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。

主从集群结构

下图就是一个简单的Redis主从集群结构:
在这里插入图片描述
如图所示,集群中有一个master节点、两个slave节点(现在叫replica)。当我们通过Redis的Java客户端访问主从集群时,应该做好路由:

  • 如果是写操作,应该访问master节点,master会自动将数据同步给两个slave节点
  • 如果是读操作,建议访问各个slave节点,从而分担并发压力

搭建主从集群

我们会在同一个虚拟机中利用3个Docker容器来搭建主从集群,容器信息如下:
在这里插入图片描述

启动多个Redis实例

使用docker-compose.yaml创建三个redis实例。

文件内容如下:

version: "3.2"

services:
  r1:
    image: redis
    container_name: r1
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7001"]
  r2:
    image: redis
    container_name: r2
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7002"]
  r3:
    image: redis
    container_name: r3
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7003"]

docker-compose.yml 文件基于 version: “3.2” 定义了三个 Redis 实例服务(r1、r2、r3),它们分别运行在不同的端口上(7001、7002、7003)。

配置项含义
image: redis使用官方 Redis 镜像(默认是最新版本)
container_name: r1容器名称为 r1,方便你用 docker exec -it r1 操作
network_mode: "host"使用 宿主机网络模式,容器与宿主机共享网络
entrypoint覆盖默认启动命令,直接启动 redis-server 并监听端口 7001

上传docker-compose.yml文件到自定义的redis文件中,cd redis,
执行命令,运行集群(前提是本机有redis镜像)

docker compose up -d

在这里插入图片描述
查看docker容器,发现都正常启动了:
由于采用的是host模式,我们看不到端口映射。不过能直接在宿主机通过ps命令查看到Redis进程:
在这里插入图片描述

建立集群

虽然我们启动了3个Redis实例,但是它们并没有形成主从关系。我们需要通过命令来配置主从关系:

# Redis5.0以前
slaveof <masterip> <masterport>
# Redis5.0以后
replicaof <masterip> <masterport>

有临时和永久两种模式(一般采用临时的,便于更改):

  • 永久生效:在redis.conf文件中利用slaveof命令指定master节点
  • 临时生效:直接利用redis-cli控制台输入slaveof命令,指定master节点

我们测试临时模式,首先连接r2,让其以r1为master

# 连接r2
docker exec -it r2 redis-cli -p 7002 # 进入redis客户端操作
# 认r1主,也就是7001
slaveof 192.168.150.101 7001

然后连接r3,让其以r1为master

# 连接r3
docker exec -it r3 redis-cli -p 7003
# 认r1主,也就是7001
slaveof 192.168.150.101 7001

然后连接r1,查看集群状态:

# 连接r1
docker exec -it r1 redis-cli -p 7001
# 查看集群状态
info replication

在这里插入图片描述
可以看到,当前节点r1:7001的角色是master,有两个slave与其连接:

  • slave0:port是7002,也就是r2节点
  • slave1:port是7003,也就是r3节点

测试

依次在r1、r2、r3节点上执行下面命令:

set num 123

get num

你会发现,只有在r1这个节点上可以执行set命令(写操作),其它两个节点只能执行get命令(读操作)。也就是说读写操作已经分离了。

主从同步原理

在刚才的主从测试中,我们发现r1上写入Redis的数据,在r2和r3上也能看到,这说明主从之间确实完成了数据同步。
那么这个同步是如何完成的呢?

全量同步

主从第一次建立连接时,会执行全量同步,将master节点的所有数据都拷贝给slave节点,流程:
在这里插入图片描述
这里有一个问题,master如何得知salve是否是第一次来同步呢??

有几个概念,可以作为判断依据:

  • Replication Id:简称replid,是数据集的标记,replid一致则是同一数据集。每个master都有唯一的replid,slave则会继承master节点的replid
  • offset:偏移量,随着记录在repl_baklog中的数据增多而逐渐增大。slave完成同步时也会记录当前同步的offset。如果slave的offset小于master的offset,说明slave数据落后于master,需要更新。

根据Replication Id是否一致来判断是不是第一次同步:如果是第一次同步,主从节点的replid不同,如果是断开重连,主从节点的replid相同

因此slave做数据同步,必须向master声明自己的replication id 和offset,master才可以判断到底需要同步哪些数据。

由于我们在执行slaveof命令之前,所有redis节点都是master,有自己的replid和offset。
当我们第一次执行slaveof命令,与master建立主从关系时,发送的replid和offset是自己的,与master肯定不一致。
master判断发现slave发送来的replid与自己的不一致,说明这是一个全新的slave,就知道要做全量同步了。
master会将自己的replid和offset都发送给这个slave,slave保存这些信息到本地。自此以后slave的replid就与master一致了。

因此,master判断一个节点是否是第一次同步的依据,就是看replid是否一致。流程如图:
在这里插入图片描述
完整流程描述:

  • slave节点请求增量同步
  • master节点判断replid,发现不一致,拒绝增量同步(必须全量同步
  • master将完整内存数据生成RDB,发送RDB到slave
  • slave清空本地数据,加载master的RDB(Redis Database Backup file是Redis数据持久化的一种方式,也被称为Redis数据快照
  • master将RDB期间的命令记录在repl_baklog,并持续将log中的命令发送给slave
  • slave执行接收到的命令,保持与master之间的同步

Redis主从同步的两种方式

同步方式触发条件特点
全量同步master和slave的复制状态不一致重新发送完整数据RDB,开销较大
增量同步状态一致,slave缺部分数据只发送缺失命令,效率高

来看下r1节点的运行日志:
在这里插入图片描述
再看下r2节点执行replicaof命令时的日志:
在这里插入图片描述
与我们描述的完全一致。

增量同步

全量同步需要先做RDB,然后将RDB文件通过网络传输给slave,成本太高了。因此除了第一次做全量同步,其它大多数时候slave与master都是做增量同步。
什么是增量同步?就是只更新slave与master存在差异的部分数据。如图:
在这里插入图片描述

repl_baklog原理

那么master怎么知道slave与自己的数据差异在哪里呢?

这就要说到全量同步时的repl_baklog文件了。这个文件是一个固定大小的数组,只不过数组是环形,也就是说角标到达数组末尾后,会再次从0开始读写,这样数组头部的数据就会被覆盖。

repl_baklog中会记录Redis处理过的命令及offset,包括master当前的offset,和slave已经拷贝到的offset:
在这里插入图片描述
slave与master的offset之间的差异,就是salve需要增量拷贝的数据了。

随着不断有数据写入,master的offset逐渐变大,slave也不断的拷贝,追赶master的offset:
[图片]
直到数组被填满:
在这里插入图片描述
此时,如果有新的数据写入,就会覆盖数组中的旧数据。不过,旧的数据只要是绿色的,说明是已经被同步到slave的数据,即便被覆盖了也没什么影响。因为未同步的仅仅是红色部分:
在这里插入图片描述

但是,如果slave出现网络阻塞,导致master的offset远远超过了slave的offset:
在这里插入图片描述
如果master继续写入新数据,master的offset就会覆盖repl_baklog中旧的数据,直到将slave现在的offset也覆盖:
在这里插入图片描述
棕色框中的红色部分,就是尚未同步,但是却已经被覆盖的数据。此时如果slave恢复,需要同步,却发现自己的offset都没有了,无法完成增量同步了。只能做全量同步。

repl_baklog大小有上限(默认1MB),写满后会覆盖最早的数据。如果slave断开时间过久,导致尚未备份的数据被覆盖,则无法基于repl_baklog做增量同步,只能再次全量同步。

主从同步优化

主从同步可以保证主从数据的一致性,非常重要。

可以从以下几个方面来优化Redis主从就集群:

  • 在master中配置repl-diskless-sync yes启用无磁盘复制,避免全量同步时的磁盘IO。
  • Redis单节点上的内存占用不要太大(一般不要超过8G),减少RDB导致的过多磁盘IO
  • 适当提高repl_baklog的大小,发现slave宕机时尽快实现故障恢复,尽可能避免全量同步
  • 限制一个master上的slave节点数量,如果实在是太多slave,则可以采用主-从-从链式结构,减少master压力
    你列出的这四条 Redis 主从优化建议,针对的是 主从同步的性能问题和高可用性设计,尤其关注:全量同步压力磁盘IO负载主节点稳定性。以下是逐条详细解释与背景原理。

1. ✅ 在 master 中配置 repl-diskless-sync yes 启用无磁盘复制,避免全量同步时的磁盘 IO

原因:

  • 默认 Redis 在全量同步时,主节点会先将内存数据生成 RDB 文件写入磁盘,再从磁盘读出来发送给 slave。
  • 这样会产生大量磁盘读写,尤其当内存数据很大时,容易导致 磁盘 I/O 阻塞,影响正常服务。

优化目的:

  • 启用无磁盘复制后,主节点不落盘,而是直接将内存中的数据流生成并发送给 slave。
  • 避免高并发下磁盘写入瓶颈,提高同步速度,特别适用于 内存大、IO性能一般的服务器

2. ✅ Redis 单节点上的内存占用不要太大,减少 RDB 导致的过多磁盘 IO

原因:

  • RDB 快照是 Redis 的默认持久化方式,触发时 Redis 会将 整个内存快照写入磁盘

  • 内存越大,RDB 文件越大,写磁盘的负担越重,容易引起:

    • 服务卡顿(磁盘IO瓶颈)
    • Linux 内核的内存写时复制(Copy-on-Write)开销高
    • Redis fork 进程时系统负载陡增

优化建议:

  • 单个 Redis 节点内存使用控制在10~20GB以内较为合理(视服务器性能)。
  • 大规模数据可采用 Redis Cluster 分片存储,避免单点过重。

3. ✅ 适当提高 repl_backlog_size,发现 slave 宕机时尽快实现故障恢复,尽可能避免全量同步

背景:

  • Redis 为了支持 增量同步,会在主节点维持一个 复制积压缓冲区(repl_backlog),缓存最近一段时间写操作的命令。
  • 如果 slave 断开连接短暂宕机,重连时可从 backlog 中 获取缺失的命令,实现增量同步。

问题:

  • 如果 backlog 缓冲太小,slave 重连后发现缺失命令已被覆盖,就无法增量同步 → 只能全量同步(代价大)。

优化建议:

  • 增加 backlog 大小,提高增量同步成功概率,降低全量同步发生频率。

  • 设置示例(单位字节):

    repl-backlog-size 64mb
    

4. ✅ 限制一个 master 上的 slave 节点数量,如果 slave 太多,采用主-从-从链式结构,减少 master 压力

原因:

  • 每个 slave 都会从 master 同步数据,同时拉取 RDB 或命令流,会导致:

    • master 网络带宽压力大
    • master CPU 负载升高,处理多个 slave 同步的 fork、IO 开销增加
    • 特别是多个 slave 同时全量同步,会导致 同步风暴,影响主服务

解决方案:

  • 合理限制 master 上的 slave 数量,如 2~3 个。
  • 大量 slave 需求时,使用 主-从-从链式结构(延迟复制),如:
master
  └── slave1(一级,从 master)
         └── slave2、slave3(从 slave1)
  • 这样 master 只服务一个 slave,slave1 分担同步压力,适合读多写少的场景,也方便构建冗余结构。

补充图示:

           大量直接挂载slave(低效)
           master
           ├── slave1
           ├── slave2
           └── slave3

           优化后链式结构(推荐)
           master
             └── slave1
                   ├── slave2
                   └── slave3

在这里插入图片描述


总结(表格版):

优化点原因与目的推荐配置/做法
启用无磁盘复制避免RDB写磁盘I/O,提升同步效率repl-diskless-sync yes
控制Redis单节点内存占用降低RDB触发的IO/系统负载每节点内存建议 ≤ 20GB
增大复制积压缓冲区提高增量同步成功率,避免全量同步repl-backlog-size 64mb
限制slave数量,链式复制减轻master压力,提高同步稳定性1主-1从-多从层次结构

简述全量同步和增量同步区别?

  • 全量同步:master将完整内存数据生成RDB,发送RDB到slave。后续命令则记录在repl_baklog,逐个发送给slave。
  • 增量同步:slave提交自己的offset到master,master获取repl_baklog中从offset之后的命令给slave

什么时候执行全量同步?

  • slave节点第一次连接master节点时
  • slave节点断开时间太久,repl_baklog中的offset已经被覆盖时

什么时候执行增量同步?

  • slave节点断开又恢复,并且在repl_baklog中能找到offset时

Redis哨兵

主从结构中master节点的作用非常重要,一旦故障就会导致集群不可用。那么有什么办法能保证主从集群的高可用性呢?

哨兵工作原理

Redis提供了哨兵(Sentinel)机制来监控主从集群监控状态,确保集群的高可用性。

哨兵作用

哨兵集群作用原理图:
在这里插入图片描述
哨兵的核心作用

作用详细说明
1️⃣ 故障检测(Monitoring)定期 Ping 主从节点,判断节点是否“下线”(网络故障或宕机)
2️⃣ 自动故障转移(Failover)主节点宕机后,自动挑选一个从节点升级为“新的主节点”,并通知其他从节点重新复制它,当故障实例恢复后会成为slave
3️⃣ 通知(Notification)通过 API 或日志通知管理员,或者通知客户端更新主节点信息
4️⃣ 配置自动更新(Reconfig)重新配置其他从节点复制新主,哨兵之间共享集群信息

那么问题来了,Sentinel怎么知道一个Redis节点是否宕机呢?

状态监控

Redis Sentinel 的故障检测机制是其核心功能之一,它通过主动探测和集群间协作,精准判断主节点是否宕机,并决定是否触发主从切换。以下是详细的实现原理和流程:


故障检测机制的两种层级
故障类型英文术语判定者含义
主观下线Subjectively Down (SDOWN)单个 SentinelSentinel 自己认为节点不可达
客观下线Objectively Down (ODOWN)多个 Sentinel 一致认定多数 Sentinel 投票确认节点真的宕机

主观下线(SDOWN)判定流程
1. 哨兵定期 Ping 所有被监控的节点(master/slave/peer sentinel):
  • 时间间隔:每 1 秒一次(由参数 sentinel down-after-milliseconds 决定)
  • 响应超时则认为该节点“不可达”
2. 哨兵判断标准:
sentinel down-after-milliseconds <milliseconds>
  • 如果在这个时长内多次 Ping 失败,则标记为 主观下线 SDOWN
  • 默认值如 30000ms(30秒),你可以调小,比如 5000ms(5秒)提升响应速度。
举例:
  • down-after-milliseconds 5000:5秒内未响应,则 Sentinel 认为该节点“主观下线”。

三、客观下线(ODOWN)判定流程
为什么需要 ODOWN?
  • 单个 Sentinel 误判风险高(如自身网络抖动)。
  • 多个 Sentinel 相互通信,投票决定是否真的故障 → 提高可靠性。
投票机制:
  • 触发前提:已有 Sentinel 标记某节点 SDOWN

  • Sentinel 之间通过 Pub/Sub 频道 __sentinel__:hello 广播状态

  • 多个 Sentinel 协商并投票:

    • 如果大多数 Sentinel 也认为 SDOWN,则升级为 ODOWN(客观下线)
影响配置:
sentinel quorum <N>
  • 表示至少有 N 个 Sentinel 同意,才判定为 ODOWN。

  • 示例:sentinel monitor mymaster 192.168.1.100 6379 2

    • 表示有2个以上 Sentinel同意,才 ODOWN。

关键时间与状态参数总结
参数作用示例
down-after-milliseconds单 Sentinel 判定 SDOWN 的时间阈值5000(5秒)
sentinel quorum判定 ODOWN 所需最小 Sentinel 数2、3 等
failover-timeout故障转移最大容忍时间,超时则取消默认 60 秒
parallel-syncs新主选出后允许多少个 slave 同步1(默认)

实际检测通信方式
  • PING/RESPONSE

    • Sentinel 向每个节点发送 PING
    • 接收到 PONG 或命令响应认为在线
    • 否则计入失败
  • Pub/Sub 协议(哨兵间通信):

    • 通过 Redis Channel __sentinel__:hello 共享状态、协调选主
    • 每 2 秒广播一次,维持哨兵间共识

故障检测流程图(简化)
1. Sentinel Ping master → 无响应 → 标记 SDOWN
2. Sentinel 广播 hello → 其他 Sentinel 同意 SDOWN
3. 达到 quorum → 标记 ODOWN
4. 选主、failover、通知 slave、恢复主从结构

可视化举例(3 个哨兵,2 个投票 quorum)
Sentinel发现 master 宕机?标记 SDOWN?投票数是否 ODOWN?
Sentinel12/3
Sentinel22/3
Sentinel3否(网络抖动)

结果:2/3 同意 → ODOWN 成立,触发自动故障转移。


总结:Sentinel 故障检测核心价值
功能实现机制配置关键点
主观下线 SDOWN单 Sentinel 多次 Ping 失败down-after-milliseconds
客观下线 ODOWN多 Sentinel 协议,投票达 quorum 成立sentinel quorum
高可用自动切换判定 ODOWN 后自动 Failoverfailover-timeout, parallel-syncs

选举leader

首先,Sentinel集群要选出一个执行failover的Sentinel节点,可以成为leader。要成为leader要满足两个条件:

  • 最先获得超过半数的投票
  • 获得的投票数不小于quorum值

而sentinel投票的原则有两条:

  • 优先投票给目前得票最多的
  • 如果目前没有任何节点的票,就投给自己
    比如有3个sentinel节点,s1、s2、s3,假如s2先投票:
  • 此时发现没有任何人在投票,那就投给自己。s2得1票
  • 接着s1和s3开始投票,发现目前s2票最多,于是也投给s2,s2得3票
  • s2称为leader,开始故障转移

不难看出,谁先投票,谁就会称为leader,那什么时候会触发投票呢?
答案是第一个确认master客观下线的人会立刻发起投票,一定会成为leader。

OK,sentinel找到leader以后,该如何完成failover呢?

当 Redis Sentinel 选出一个新的 master 节点后,它会自动完成身份切换的全过程,让整个主从集群重新恢复正常的“1主多从”结构。这个身份切换分为 3 个阶段:提升新主、重配置其他从、通知客户端


一、整体流程图(简化)
master宕机 →
Sentinel判定ODOWN →
选出slaveX作为新master →
1. slaveX身份切换为master
2. 其他slave重新复制新master
3. 客户端更新连接信息

二、详细步骤解析
步骤 1:提升新 master(slave → master)
  • Sentinel 通过 命令控制选定的 slave,提升为新主。

  • 执行命令:

    SLAVEOF NO ONE
    

    含义:取消对旧 master 的复制,成为新的 master。

  • 日志会显示:

    promoted slave 192.168.1.102:6379 as new master
    

步骤 2:其他 slave 重定向复制新 master
  • Sentinel 向其他 slave 发送命令:

    SLAVEOF <new_master_ip> <port>
    
  • 这些 slave 停止复制旧 master,开始同步新 master。

  • 例如:

    SLAVEOF 192.168.1.102 6379
    
  • 通过 info replication 可以验证角色变化:

    • 新 master:

      role:master
      connected_slaves:N
      
    • 旧 slave:

      role:slave
      master_host:192.168.1.102
      

步骤 3:通知客户端更新连接
  • 客户端通过 Sentinel 动态获取当前主节点地址:

    SENTINEL get-master-addr-by-name <master_name>
    

    返回值(新的主IP + 端口):

    192.168.1.102 6379
    
  • 客户端收到新主信息,自动切换连接(前提:客户端支持 Sentinel 机制,如 Jedis、Lettuce、go-redis 等)。


三、身份切换的持久化与传播
机制说明
Sentinel 配置自动更新Sentinel 会修改自己的配置文件(如 sentinel.conf)写入新的主节点信息
哨兵间广播Sentinel 通过 Pub/Sub 互相通知主从变化,保持共识一致性

四、特殊情况处理(旧 master 恢复)
  • 原 master 恢复上线后:

    • 会发现自己不是 master 了;

    • Sentinel 会强制它降级为从节点,执行:

      SLAVEOF <new_master_ip> <port>
      
  • 避免出现“脑裂”问题,保证唯一 master。


五、配置相关参数(控制切换行为)
参数作用示例
failover-timeout故障转移允许的最长时间(毫秒)60000(1分钟)
parallel-syncs同时有几个 slave 可同步新 master1 或更多
down-after-milliseconds多久未响应判为 SDOWN5000
quorum判定 ODOWN 所需 Sentinel 数量2,3 等

六、总结:身份切换自动完成,不需要人工干预
动作由谁执行是否自动
选主Sentinel 投票✅ 自动
新主切换Sentinel 命令控制✅ 自动
从节点重配置Sentinel 控制✅ 自动
客户端主地址更新客户端请求 Sentinel✅ 自动(需支持)

搭建哨兵集群

首先,我们停掉之前的redis集群:

# 老版本DockerCompose
docker-compose down
# 新版本Docker
docker compose down

然后,我们找到sentinel.conf文件:
内容如下:

sentinel announce-ip "192.168.150.101"
sentinel monitor hmaster 192.168.150.101 7001 2
sentinel down-after-milliseconds hmaster 5000
sentinel failover-timeout hmaster 60000

说明:

  • sentinel announce-ip “192.168.150.101”:声明当前sentinel的ip
  • sentinel monitor hmaster 192.168.150.101 7001 2:指定集群的主节点信息
    • hmaster:主节点名称,自定义,任意写
    • 192.168.150.101 7001:主节点的ip和端口
    • 2:认定master下线时的quorum值
  • sentinel down-after-milliseconds hmaster 5000:声明master节点超时多久后被标记下线
  • sentinel failover-timeout hmaster 60000:在第一次故障转移失败后多久再次重试

我们在虚拟机的/root/redis目录下新建3个文件夹:s1、s2、s3:
在这里插入图片描述
将sentinel.conf文件分别拷贝一份到3个文件夹中(记得修改自己虚拟机的ip地址)。
在这里插入图片描述

接着修改docker-compose.yaml文件,内容如下(记得删除原来的redis集群):

version: "3.2"

services:
  r1:
    image: redis
    container_name: r1
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7001"]
  r2:
    image: redis
    container_name: r2
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7002", "--slaveof", "192.168.100.140", "7001"]
  r3:
    image: redis
    container_name: r3
    network_mode: "host"
    entrypoint: ["redis-server", "--port", "7003", "--slaveof", "192.168.100.140", "7001"]
  s1:
    image: redis
    container_name: s1
    volumes:
      - /root/redis/s1:/etc/redis
    network_mode: "host"
    entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27001"]
  s2:
    image: redis
    container_name: s2
    volumes:
      - /root/redis/s2:/etc/redis
    network_mode: "host"
    entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27002"]
  s3:
    image: redis
    container_name: s3
    volumes:
      - /root/redis/s3:/etc/redis
    network_mode: "host"
    entrypoint: ["redis-sentinel", "/etc/redis/sentinel.conf", "--port", "27003"]

依然是redis镜像。redis镜像既可以部署主从集群,也可以部署哨兵集群

直接运行命令,启动集群:

docker-compose up -d

运行结果:
在这里插入图片描述
我们以s1节点为例,查看其运行日志(docker logs -f s1):
日志输出结果:

1:X 03 Aug 2025 13:59:22.444 # Sentinel ID is f6ded23a7a21c855785a38f7185400715968e8b4
1:X 03 Aug 2025 13:59:22.444 # +monitor master hmaster 192.168.100.140 7001 quorum 2
1:X 03 Aug 2025 13:59:22.444 * +slave slave 192.168.100.149:7002 192.168.100.149 7002 @ hmaster 192.168.100.140 7001
1:X 03 Aug 2025 13:59:24.453 * +sentinel sentinel 7df3a1066614e137b62663d915d7094afd0a60a1 192.168.100.140 27002 @ hmaster 192.168.100.140 7001
1:X 03 Aug 2025 13:59:24.460 * +sentinel sentinel c6ad53e2bcd4c3333ba4f2551122364740fe9126 192.168.100.140 27003 @ hmaster 192.168.100.140 7001
1:X 03 Aug 2025 13:59:32.510 * +slave slave 192.168.100.149:7003 192.168.100.149 7003 @ hmaster 192.168.100.140 7001

系统状态

组件状态
master192.168.100.140:7001 正常运行,被监控中
slave1192.168.100.149:7002 正常运行,复制 master
slave2192.168.100.149:7003 正常运行,复制 master
Sentinel 节点s1(本机)+ s2(27002)+ s3(27003)都已发现并互联

演示failover

接下来,我们演示一下当主节点故障时,哨兵是如何完成集群故障恢复(failover)的。

我们连接7001这个master节点,然后通过命令让其休眠60秒,模拟宕机:

# 连接7001这个master节点,通过sleep模拟服务宕机,60秒后自动恢复
docker exec -it r1 redis-cli -p 7001 DEBUG sleep 60

稍微等待一段时间后,会发现sentinel节点触发了failover:
在这里插入图片描述

总结

Sentinel的三个作用是什么?

  • 集群监控
  • 故障恢复
  • 状态通知
  • 配置自动更新(Reconfig)(新增)

Sentinel如何判断一个redis实例是否健康?

  • 每隔1秒发送一次ping命令,如果超过一定时间没有响应则认为是主观下线(sdown)
  • 如果大多数sentinel都认为实例主观下线,则判定服务客观下线(odown)

故障转移步骤有哪些?

  • 首先要在sentinel中选出一个leader,由leader执行failover
  • 选定一个slave作为新的master,执行slaveof noone,切换到master模式
  • 然后让所有节点都执行slaveof 新master
  • 修改故障节点配置,添加slaveof 新master

sentinel选举leader的依据是什么?

  • 票数超过sentinel节点数量1半
  • 票数超过quorum数量
  • 一般情况下最先发起failover的节点会当选

sentinel从slave中选取master的依据是什么?

  • 首先会判断slave节点与master节点断开时间长短,如果超过down-after-milliseconds * 10则会排除该slave节点
  • 然后判断slave节点的slave-priority值,越小优先级越高,如果是0则永不参与选举(默认都是1)。
  • 如果slave-prority一样,则判断slave节点的offset值,越大说明数据越新,优先级越高
  • 最后是判断slave节点的run_id大小,越小优先级越高(通过info server可以查看run_id)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值