13、Docker Compose 安装 Redis 哨兵集群(一主两从)
🚀CentOS 9 使用 Docker Compose 安装 Redis 哨兵集群(一主两从)
📌 适用系统:CentOS 9、支持 Ubuntu / RHEL / Mac 调整后使用
🔧 工具版本:Docker 25+、Docker Compose v2+
🧠 一、什么是 Redis Sentinel 哨兵?
Redis Sentinel 是 Redis 官方提供的高可用解决方案,能实现以下功能:
- 自动故障转移(主挂了自动切换从为主)
- 主从节点监控(心跳检测)
- 通知(通过 pub/sub 发布警告)
- 配置自动更新(Sentinel 自动通知客户端主库变动)
📐 二、集群架构图
+----------------+| Client App |+--------+-------+|+-----v------+| Sentinel1 |+-----+------+|+----------------+ +----------+----------+ +----------------+| Redis 主节点 |<--->| Sentinel2 |<--->| Redis 从节点1 |+----------------+ +----------+----------+ +----------------+|+-----+------+| Sentinel3 |+-----+------+|+--------v--------+| Redis 从节点2 |+----------------+
✅ 所有 Redis 节点运行在 Docker 容器中,使用
Docker Compose
管理。
📁 三、准备目录结构
mkdir -p redis-cluster/{master,slave1,slave2,sentinel}
cd redis-cluster
🧾 四、配置文件
4.1 主节点配置:master/redis.conf
port 6379
bind 0.0.0.0
protected-mode no
appendonly yes
配置项 | 作用说明 | 详细解释 | 安全/使用建议 |
---|---|---|---|
port 6379 | 指定 Redis 监听的 TCP 端口号 | Redis 默认端口为 6379,客户端通过此端口连接 Redis 服务 | 保持默认即可,如有冲突可调整,但需确保客户端同步修改端口访问设置 |
bind 0.0.0.0 | 指定 Redis 监听的网络接口 IP | 0.0.0.0 表示监听所有网卡和所有 IP 地址,允许任何 IP 访问 | 生产环境建议绑定内网 IP 或特定 IP,避免外网暴露,配合防火墙使用 |
protected-mode no | 关闭 Redis 保护模式 | Redis 默认启用保护模式,防止未授权访问;关闭后允许无密码的外部访问 | 关闭保护模式有风险,生产环境建议开启保护模式或设置访问密码(requirepass ) |
appendonly yes | 开启 AOF(追加文件)持久化 | 通过追加写命令日志实现数据持久化,重启时可恢复所有写操作 | 推荐生产环境开启,保障数据安全,但写入性能稍有开销 |
4.2 从节点配置(slave1/redis.conf、slave2/redis.conf)
port 6379
bind 0.0.0.0
protected-mode no
replicaof redis-master 6379
appendonly yes
配置项 | 作用说明 | 详细解释 | 安全/使用建议 |
---|---|---|---|
replicaof redis-master 6379 | 配置当前实例为指定主节点的从节点(复制主节点数据) | 将本 Redis 实例作为主节点 redis-master 的从节点,连接端口 6379,同步主节点数据 | 确保主节点 redis-master 名称在网络中可解析,且端口正确 |
🔁 注意
replicaof
设置的是主节点的服务名称,Compose 启动后自动识别。
4.3 哨兵配置:sentinel/sentinel.conf
port 26379
bind 0.0.0.0
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 10000
sentinel parallel-syncs mymaster 1
配置项 | 含义(简短) | 详细解释 | 建议 / 注意事项 |
---|---|---|---|
port 26379 | Sentinel 监听端口 | Sentinel 默认监听 26379 端口,客户端(或管理脚本)可通过该端口与 Sentinel 通信(比如 redis-cli -p 26379 )。 | 默认即可;如果宿主机要映射多个 Sentinel,映射端口要不冲突。 (Redis) |
bind 0.0.0.0 | 监听所有网络接口 | 指示 Sentinel 在容器/主机的所有网卡上接受连接(等同于监听所有 IP)。在 Docker 环境下通常需要这样以使外部能连到 26379。 | 生产环境注意访问控制(防火墙/安全组);不要随意暴露到公网。 |
sentinel monitor mymaster redis-master 6379 2 | 监控一个主节点(mymaster) | 格式:sentinel monitor <ip hostname> 。- mymaster :给主节点的逻辑名字(sentinel 内部识别用)。- redis-master :主节点 IP 或主机名(sentinel 将尝试连接它)。- 6379 :主节点端口。- 2 :quorum(判定 master 下线所需的最少 sentinel 投票数)。 | Sentinel 会监控该主节点并参与故障判定与故障转移。quorum` 表示判定主节点下线所需的最少 Sentinel 投票数。 |
sentinel down-after-milliseconds mymaster 5000 | 判定为下线的超时阈值 | 表示 sentinel 认为 master“疑似下线”的时间阈值(毫秒),超过这个值 sentinel 会把实例标记为 sdown (subjectively down,由单个 sentinel 判断)。 | 值越小检测越快但误判风险越高;生产环境常见 5s~30s 取值,视网络稳定性调整。 (Redis) |
sentinel failover-timeout mymaster 10000 | 整个故障转移流程超时 | 表示一次故障转移允许的最长时间(毫秒)。包含选举 leader、选举 promoted replica、执行复制重设等操作。超时后该次 failover 会被视为失败,允许再次尝试。 | 过小可能导致 failover 被中断,过大则恢复慢。生产可按网络与复制稳定性调整(比如 30s-120s)。 (Redis) |
sentinel parallel-syncs mymaster 1 | 并行同步的从节点数 | 当 promote(选举某个 replica 为新 master)后,旧 master 或新 master 会和 replicas 做重同步(replication sync)。该项限制在重建复制关系时可同时并行同步的 replicas 数量。 | 如果有多个 replica,可适当调大以加快同步,但并行数越多对新 master 负载越大。 |
sentinel resolve-hostnames yes | 允许使用主机名并解析它们 | 启用后 sentinel 接受 sentinel monitor 中的主机名(而非仅限 IP),并在运行时解析这些主机名(DNS)。这对于容器/ k8s / TLS 场景下通过主机名连接很有用。 | 注意:启用后 sentinel 会解析主机名但内部或配置文件仍可能以 IP 写入;若要让 sentinel/redis 使用主机名作为公告信息,还需要 announce-hostnames 等配合设置。如果 sentinel 版本过旧(< 6.2)或运行环境 DNS 不可用,仍会报 “Can’t resolve hostname”。 (Redis, Stack Overflow) |
为什么配置sentinel resolve-hostnames yes
📦 五、Docker Compose 文件 docker-compose.yml
version: '3.8'services:redis-master:image: redis:7.2container_name: redis-mastervolumes:- ./master/redis.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confports:- "6379:6379"networks:- redis-netredis-slave1:image: redis:7.2container_name: redis-slave1volumes:- ./slave1/redis.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confdepends_on:- redis-masterports:- "6380:6379"networks:- redis-netredis-slave2:image: redis:7.2container_name: redis-slave2volumes:- ./slave2/redis.conf:/usr/local/etc/redis/redis.confcommand: redis-server /usr/local/etc/redis/redis.confdepends_on:- redis-masterports:- "6381:6379"networks:- redis-netsentinel1:image: redis:7.2container_name: sentinel1volumes:- ./sentinel/sentinel.conf:/etc/redis/sentinel.confcommand: redis-sentinel /etc/redis/sentinel.confdepends_on:- redis-master- redis-slave1- redis-slave2ports:- "26379:26379"networks:- redis-netsentinel2:image: redis:7.2container_name: sentinel2volumes:- ./sentinel/sentinel.conf:/etc/redis/sentinel.confcommand: redis-sentinel /etc/redis/sentinel.confnetworks:- redis-netsentinel3:image: redis:7.2container_name: sentinel3volumes:- ./sentinel/sentinel.conf:/etc/redis/sentinel.confcommand: redis-sentinel /etc/redis/sentinel.confnetworks:- redis-netnetworks:redis-net:driver: bridge
一、整体结构概览
配置项 | 说明 |
---|---|
version | 指定 Docker Compose 文件版本,确保兼容性 |
services | 定义所有容器服务,包含 Redis 主从和 Sentinel |
networks | 自定义网络,保障容器间通信与 DNS 解析 |
二、服务详解
服务名 | 关键配置 | 详细说明 |
---|---|---|
redis-master | image | 使用官方 Redis 7.2 镜像 |
container_name | 指定容器名,方便管理与访问 | |
volumes | 挂载宿主机配置文件,覆盖容器内默认配置 | |
command | 启动 Redis 并加载指定配置文件 | |
ports | 映射宿主机 6379 端口,允许外部访问主节点 | |
networks | 加入自定义桥接网络,实现容器间通信 | |
redis-slave1 | depends_on | 依赖 redis-master ,保证主节点先启动 |
ports | 映射宿主机 6380 到容器 6379,方便访问从节点 | |
其他配置与主节点类似 | ||
redis-slave2 | depends_on | 同样依赖 redis-master |
ports | 映射宿主机 6381 端口 | |
其他配置同上 | ||
sentinel1 | volumes | 挂载哨兵配置文件 |
command | 使用 redis-sentinel 命令启动哨兵 | |
depends_on | 确保主从节点先启动,保证哨兵能正常监控 | |
ports | 映射宿主机 26379 端口,方便外部连接 | |
networks | 加入同一自定义网络,保证与 Redis 容器通信 | |
sentinel2 & sentinel3 | 配置同 sentinel1 | 适合内部高可用哨兵集群,避免端口冲突 |
三、网络配置详解
网络名 | 类型 | 说明 |
---|---|---|
redis-net | bridge | 桥接网络,允许容器之间通过名称进行通信和 DNS 解析 |
四、总结与建议
优势 | 说明 |
---|---|
自定义桥接网络 | 保证容器间主机名解析,Sentinel 能正确识别主节点地址 |
统一挂载配置文件 | 易于管理 Redis 和 Sentinel 配置 |
启动顺序依赖管理 | 避免哨兵启动时主从不可用导致监控失败 |
多哨兵部署 | 提升故障检测准确性和自动切换的可靠性 |
注意事项 | 说明 |
---|---|
Sentinel 配置需开启 resolve-hostnames yes | 确保 Sentinel 能解析主机名,如 redis-master |
端口映射仅对主哨兵开放 | 一般只需暴露一个哨兵端口,避免端口冲突 |
🚀 六、启动服务
docker compose up -d
查看容器状态:
docker ps
📌 确保所有服务都成功启动。
🔍 七、验证 Sentinel 状态
进入任一哨兵容器:
docker exec -it sentinel1 redis-cli -p 26379
查看主从信息:
SENTINEL get-master-addr-by-name mymaster
SENTINEL masters
SENTINEL slaves mymaster
模拟主节点故障:
docker stop redis-master
查看哨兵是否切换主从:
SENTINEL get-master-addr-by-name mymaster
SENTINEL masters
SENTINEL slaves mymaster
查看从
配置,发现已经剩下一个了。
🧰 八、常见问题排查
问题 | 解决方案 |
---|---|
sentinel 无法识别 master IP | 使用服务名(如 redis-master),不要用 127.0.0.1 |
主挂后未切换 | 是否至少有 2 个 Sentinel 进程?配置 quorum 是否正确? |
端口冲突 | 检查宿主机端口映射是否唯一 |
redis-cli 连接失败 | 检查 bind 和 protected-mode 设置是否允许远程连接 |
🧠 九、为什么需要三个 Sentinel 守护节点?
在 Redis Sentinel 架构中,Sentinel 节点用于监控主节点、自动进行主从切换(Failover)以及通知客户端主节点变化。至少部署三个 Sentinel 守护节点,是保障高可用性的核心策略,原因如下:
✅ 1. 多数投票机制:支持故障仲裁
Redis Sentinel 采用投票机制决定主节点是否故障,以及选择新的主节点。
- 必须获得超过半数 Sentinel 的认可,才会真正执行主从切换。
- 如果 Sentinel 数量过少(如 1 或 2 个),无法进行有效仲裁。
Sentinel 数量 | 多数派数量 | 可容忍故障数 | 是否推荐 |
---|---|---|---|
1 | 1 | 0 | ❌ 极易误判,单点故障 |
2 | 2 | 0 | ❌ 无法容错 |
3 | 2 | 1 | ✅ 推荐 |
5 | 3 | 2 | ✅ 更高容错 |
📌 三个 Sentinel 节点是实现仲裁和容错的最小安全数量。
🚨 2. 防止脑裂和误切换
- 如果 Sentinel 误判主节点宕机,会导致系统切换到错误的从节点,发生“脑裂”。
- 多个 Sentinel 可以通过协商与共识机制,确保判断更准确、稳定。
🔄 3. 客户端服务发现更稳定
客户端通常通过 Sentinel 查询主节点地址:
SENTINEL get-master-addr-by-name mymaster
若 Sentinel 节点过少或出现故障,客户端将无法获得主节点信息,导致连接失败。多个 Sentinel 可提升服务发现的高可用性。
📌 官方推荐配置
Redis 官方建议:
哨兵节点数量应为 奇数,且至少为 3 个,才能保证在任意一个 Sentinel 宕机时,系统仍具备自动切换能力。
🧾 总结
理由 | 说明 |
---|---|
✔ 多数派投票机制 | 至少 3 个才能投票成功,选出新主节点 |
✔ 容错性强 | 容忍任意一个 Sentinel 宕机 |
✔ 服务发现高可用 | 客户端随时可连接其他 Sentinel 查询主信息 |
✔ 防止误切换 | 多节点协商更稳妥,避免脑裂现象 |
✔ 官方推荐 | Redis 官方明确建议部署至少 3 个 Sentinel |
如果你正在部署 Redis Sentinel,请务必记住这条经验法则:
哨兵数量:奇数且不少于 3 个,安全又稳定。
🧾 十、总结
本文展示了如何在 CentOS 9 中使用 Docker Compose 快速搭建一个包含:
- 🟥 Redis 一主两从节点
- 📡 三个 Sentinel 守护节点
的高可用 Redis 集群环境,覆盖 Redis Sentinel 高可用部署场景的 99% 使用需求。
💬 推荐阅读
- 📘 官方 Sentinel 文档
- 📘 Docker Compose 进阶使用技巧
- 📘 Redis 主从复制与高可用实践