高级篇-分布式缓存-11-Redis哨兵-搭建哨兵集群

5 阅读9分钟

这次我按你当前真实环境来整理:

  • 不动黑马点评项目里的 my-redis

  • 单独新建一套:

    • redis-master
    • redis-slave-1
    • redis-slave-2
    • sentinel-1
    • sentinel-2
    • sentinel-3
  • 重点修正:Sentinel 配置里,不用 redis-master 主机名,改用 redis-master 容器的内部 IP

  • 场景完全对应课程里的“1主2从 + 3哨兵”结构。课程资料里明确是三节点 Sentinel 集群,端口是 27001/27002/27003,并监管前面的主从集群。


一、这节课你要学会什么

这节课核心不是背命令,而是理解:

1. 为什么主从还不够

主从能解决 读写分离,但不能自动故障恢复。课程里把这个问题归纳为“故障恢复问题”,对应方案就是 利用 Redis 哨兵,实现健康检测和自动恢复

2. 哨兵的三个作用

课程里直接给出三点:

  • 监控
  • 自动故障恢复 / 故障转移
  • 通知

3. 哨兵如何判断 Redis 是否挂了

Sentinel 基于心跳机制,每隔 1 秒向实例发送 ping

  • 一个 sentinel 觉得实例没响应:主观下线
  • 超过指定数量 quorum 的 sentinel 都认为它主观下线:客观下线
  • quorum 最好超过 Sentinel 实例数量的一半。

4. master 挂了以后怎么切换

课程里的流程是:

  • 选一个 slave 作为新 master
  • 对它执行 slaveof no one
  • 其它 slave 改为复制新 master
  • 原故障 master 恢复后,会变成新 master 的 slave。

二、这节课的知识主线

你可以直接记成一句话:

哨兵 = 给 Redis 主从集群加一个“自动值班系统”

它做三件事:

  1. 盯着 master / slave 是否正常
  2. master 挂了就自动选主
  3. 告诉客户端“新主是谁”

这正是课程资料里的定义。


三、课程版标准结构

课程里的 Sentinel 集群是:

  • s1:27001
  • s2:27002
  • s3:27003

并监管前面的 Redis 主从集群。

所以你在 Docker Desktop 里,最适合搭成:

redis-master   -> 7001
redis-slave-1  -> 7002
redis-slave-2  -> 7003

sentinel-1     -> 27001
sentinel-2     -> 27002
sentinel-3     -> 27003

四、为什么你之前会报错

你这次遇到的是:

Sentinel 读取 sentinel.conf 时,无法解析 redis-master

这不是你 Redis 主从没起来,而是:

  • Sentinel 启动太快
  • Docker 内部 DNS 在那一瞬间没有及时解析
  • Redis Sentinel 启动阶段要求能立刻识别被监控 master 地址
  • 结果配置文件解析失败,直接退出

所以你现在这个环境下,最稳的做法是:Sentinel 用 master 容器的内部 IP,不用容器名

这个修正是合理的,而且也和课程里配置 sentinel monitor mymaster 192.168.150.101 7001 2 的思路一致:monitor 后面本来就是明确写主节点 IP + 端口


五、Docker Desktop 实战:重新搭一套哨兵集群

第一步:创建独立网络

打开 Docker Desktop 终端,或者 PowerShell,执行:

docker network create redis-ms-net

第二步:启动 1 主 2 从

1)启动 master

docker run -d --name redis-master --network redis-ms-net -p 7001:6379 redis:latest redis-server --bind 0.0.0.0 --protected-mode no

2)启动 slave-1

docker run -d --name redis-slave-1 --network redis-ms-net -p 7002:6379 redis:latest redis-server --bind 0.0.0.0 --protected-mode no --replicaof redis-master 6379

3)启动 slave-2

docker run -d --name redis-slave-2 --network redis-ms-net -p 7003:6379 redis:latest redis-server --bind 0.0.0.0 --protected-mode no --replicaof redis-master 6379

课程资料里主从就是 7001/7002/7003,其中 7001 是 master,7002 和 7003 是 slave。


第三步:验证主从正常

docker exec -it redis-master redis-cli info replication

如果看到:

role:master
connected_slaves:2

说明主从 OK。

课程里也是通过 info replication 查看主从状态。


六、关键修正版:先查 master 的内部 IP

这是你当前环境最关键的一步。

执行:

docker inspect -f "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}" redis-master

你会得到一个 IP,例如:

172.20.0.2

下面文档里我用 172.18.0.2 举例,你实际操作时要替换成你查到的那个 IP。


七、准备 3 份 sentinel.conf

课程资料里要求:
同一台机器上起 3 个 Sentinel,就要准备 3 份配置文件和目录

你本机新建目录:

D:\docker-redis-sentinel\s1
D:\docker-redis-sentinel\s2
D:\docker-redis-sentinel\s3

s1 的 sentinel.conf

路径:

D:\docker-redis-sentinel\s1\sentinel.conf

内容:

port 26379
bind 0.0.0.0
protected-mode no

sentinel monitor mymaster 172.18.0.2 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

dir /tmp

s2 的 sentinel.conf

路径:

D:\docker-redis-sentinel\s2\sentinel.conf

内容:

port 26379
bind 0.0.0.0
protected-mode no

sentinel monitor mymaster 172.18.0.2 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

dir /tmp

s3 的 sentinel.conf

路径:

D:\docker-redis-sentinel\s3\sentinel.conf

内容:

port 26379
bind 0.0.0.0
protected-mode no

sentinel monitor mymaster 172.18.0.2 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000

dir /tmp

八、为什么这里是 26379,不是 27001/27002/27003

课程里 27001、27002、27003 是 每个 Sentinel 实例自己的监听端口

在 Docker 里更方便的做法是:

  • 容器内部都继续监听默认 Sentinel 端口 26379

  • 宿主机映射成:

    • 27001 -> 26379
    • 27002 -> 26379
    • 27003 -> 26379

这样更简单,也更稳。


九、先清理旧的失败哨兵

如果你之前启动失败过,先删掉旧容器:

docker rm -f sentinel-1 sentinel-2 sentinel-3

十、启动 3 个 Sentinel

sentinel-1

docker run -d --name sentinel-1 --network redis-ms-net -p 27001:26379 -v "D:\docker-redis-sentinel\s1\sentinel.conf:/etc/redis/sentinel.conf" redis:latest redis-sentinel /etc/redis/sentinel.conf

sentinel-2

docker run -d --name sentinel-2 --network redis-ms-net -p 27002:26379 -v "D:\docker-redis-sentinel\s2\sentinel.conf:/etc/redis/sentinel.conf" redis:latest redis-sentinel /etc/redis/sentinel.conf

sentinel-3

docker run -d --name sentinel-3 --network redis-ms-net -p 27003:26379 -v "D:\docker-redis-sentinel\s3\sentinel.conf:/etc/redis/sentinel.conf" redis:latest redis-sentinel /etc/redis/sentinel.conf

课程资料里启动命令的本质就是 redis-sentinel sentinel.conf


十一、如何验证哨兵是否真的起来了

1)看容器

docker ps

应该看到 6 个相关容器:

  • redis-master
  • redis-slave-1
  • redis-slave-2
  • sentinel-1
  • sentinel-2
  • sentinel-3

2)看 sentinel 日志

docker logs sentinel-1

正常情况下,它会识别到:

  • 一个 master
  • 两个 slave

3)看哨兵信息

docker exec -it sentinel-1 redis-cli -p 26379 info sentinel

成功时你要重点看:

sentinel_masters:1

4)看 master 列表

docker exec -it sentinel-1 redis-cli -p 26379 sentinel masters

5)看 slave 列表

docker exec -it sentinel-1 redis-cli -p 26379 sentinel slaves mymaster

如果 mymaster 正常,说明 Sentinel 已经接管成功。


十二、这节课最重要的原理总结

1. 主观下线 vs 客观下线

主观下线

某一个 Sentinel 自己认为 Redis 没响应。

客观下线

超过 quorum 数量的 Sentinel 都认为它没响应。

课程明确说了:
每隔 1 秒发 ping,若超过 quorum 数量的 sentinel 都认为该实例主观下线,则该实例客观下线。


2. quorum 为什么一般设为 2

因为你现在是 3 个哨兵。

如果 quorum=2,代表:

至少两个哨兵都认为 master 挂了,才会执行故障转移

课程资料里 sentinel monitor mymaster ... 2 最后的 2,就是这个含义。


3. 新 master 是怎么选的

课程给出的顺序是:

  1. 跟 master 断开太久的 slave 先排除
  2. slave-priority 越小越优先,0 不参与
  3. offset 越大越优先,说明数据更新
  4. runid 越小越优先。

这个是高频面试点。


4. 故障转移流程

课程里故障转移的核心步骤是:

  1. Sentinel 选中一个 slave
  2. 给它执行 slaveof no one
  3. 给其它 slave 执行 slaveof 新master
  4. 故障节点恢复后,变成新的 slave。

十三、如何做故障演练

这一步最有意思。

1)先确认当前 master 正常

docker exec -it redis-master redis-cli info replication

2)停掉 master

docker stop redis-master

3)等 10 秒左右,再看两个 slave

docker exec -it redis-slave-1 redis-cli info replication
docker exec -it redis-slave-2 redis-cli info replication

你会发现其中一个 slave 变成新的 master。


4)再看哨兵日志

docker logs sentinel-1
docker logs sentinel-2
docker logs sentinel-3

你会看到类似:

  • 主观下线
  • 客观下线
  • 选主
  • 故障转移

这正对应课程里的 Sentinel 原理。


十四、你可以直接背的面试答案

什么是 Redis 哨兵?

Redis Sentinel 是 Redis 提供的一种高可用机制,用来对主从集群进行监控,并在 master 故障时自动完成故障转移,同时向客户端提供最新主节点信息。它的三大作用是:监控、故障转移、通知。

哨兵如何判断节点下线?

Sentinel 每隔 1 秒向 Redis 实例发送一次 ping。如果某个 Sentinel 发现实例在指定时间内没有响应,则认为它主观下线;如果超过 quorum 数量的 Sentinel 都认为它主观下线,则认定为客观下线。

master 挂了以后怎么切换?

Sentinel 会从 slave 中选出一个新的 master,先执行 slaveof no one,再让其它 slave 复制新的 master,故障节点恢复后自动成为新 master 的 slave。


十五、最适合你现在的完整操作顺序

你就按这个顺序来:

1. docker network create redis-ms-net
2. 启动 redis-master
3. 启动 redis-slave-1
4. 启动 redis-slave-2
5. docker inspect 查 redis-master 内部 IP
6. 写 3 份 sentinel.conf,把 monitor 里的主机改成这个 IP
7. docker rm -f sentinel-1 sentinel-2 sentinel-3
8. 启动 sentinel-1
9. 启动 sentinel-2
10. 启动 sentinel-3
11. docker exec sentinel-1 redis-cli -p 26379 info sentinel
12. docker stop redis-master 做故障演练

十六、最容易踩的坑

1. sentinel monitor 里写容器名

你现在这个环境里,最稳的是写 master 的内部 IP,不要写 redis-master

2. 改完配置文件没删旧容器

旧容器还在,可能会继续带着旧配置起。

3. 3 个 Sentinel 不在同一个 Docker 网络

如果不在 redis-ms-net 里,就没法正确感知 Redis 节点。

4. 还没等够时间就判断失败

你配置的是 down-after-milliseconds 5000,再加上投票和切换流程,通常要多等几秒。


十七、一句话总结本节课

Redis 主从解决读写分离,Redis 哨兵解决高可用自动切换。