Docker Compose 从零搭建 Redis 主从哨兵集群(超详细实操,避坑指南)
前言:Redis 主从复制 + 哨兵模式是企业级开发中最常用的高可用方案,能实现自动故障转移,避免单点故障导致服务不可用。本文将从 Docker Compose 安装开始,一步步搭建 Redis 1 主 2 从 3 哨兵集群,全程实操,包含所有报错解决方案,新手也能轻松上手(实测可直接投产测试环境)。
环境说明:
- 服务器:CentOS 7(云服务器 / 虚拟机均可,本文用虚拟机演示,IP:192.168.126.140)
- Docker:已安装(若未安装,文中附带简易安装步骤)
- Redis 版本:7.0.4(主从)、latest(哨兵,兼容 7.0+)
- Docker Compose 版本:v2.20.2(稳定版)
核心目标:搭建 1 主 2 从 3 哨兵集群,实现主节点故障后,哨兵自动投票选举新主节点,保证 Redis 高可用。
一、前置准备:安装 Docker(已安装可跳过)
若服务器未安装 Docker,执行以下命令快速安装(一键复制,避免输错):
# 卸载旧版本(若有)
yum remove docker docker-client docker-client-latest docker-common docker-latest docker-latest-logrotate docker-logrotate docker-engine
# 安装依赖
yum install -y yum-utils device-mapper-persistent-data lvm2
# 设置 Docker 镜像源(阿里云,加速下载)
yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo
# 安装 Docker CE
yum install -y docker-ce docker-ce-cli containerd.io
# 启动 Docker 并设置开机自启
systemctl start docker
systemctl enable docker
# 验证 Docker 是否安装成功
docker --version
出现类似 Docker version 24.0.7, build afdd53b 提示,说明 Docker 安装成功。
二、安装 Docker Compose(重点步骤)
Docker Compose 用于一键管理多容器应用,是搭建主从哨兵的核心工具,步骤如下:
2.1 下载 Docker Compose 二进制文件
# 下载最新稳定版(v2.20.2,可根据官网更新版本号)
curl -L "https://github.com/docker/compose/releases/download/v2.20.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
若下载缓慢,可替换为阿里云镜像:
curl -L "https://mirrors.aliyun.com/docker-toolbox/linux/compose/v2.20.2/docker-compose-Linux-x86_64" -o /usr/local/bin/docker-compose
2.2 赋予执行权限
chmod +x /usr/local/bin/docker-compose
2.3 验证安装
docker-compose --version
出现类似 docker-compose version v2.20.2 提示,说明 Docker Compose 安装成功。
⚠️ 避坑提示:若出现 “command not found: docker-compose”,执行 ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose 建立软链接即可。
三、搭建 Redis 主从集群(1 主 2 从)
采用 Docker Compose 管理主从容器,目录结构清晰,便于后期维护,步骤如下:
3.1 创建主从目录结构
先创建统一的工作目录,避免文件混乱(本文目录路径:/docker/docker-master-slave/redis):
# 创建多级目录
mkdir -p /docker/docker-master-slave/redis
# 进入目录(后续所有操作都在此目录下)
cd /docker/docker-master-slave/redis
3.2 编写 docker-compose.yml 文件
创建并编辑 docker-compose.yml,复制以下内容(注释详细,可直接复制):
version: '3.8' # 版本兼容 Docker Compose v2+
services:
# Redis 主节点
redis-master:
image: redis:7.0.4 # 主从用 7.0.4 稳定版
container_name: redis-master # 容器名,固定,便于哨兵识别
ports:
- "6379:6379" # 主节点端口映射
command: redis-server --requirepass 123456 --bind 0.0.0.0 # 密码123456,允许所有IP访问
volumes:
- ./master/data:/data # 数据持久化目录
networks:
- redis-network # 统一网络,主从+哨兵都在这个网络
# Redis 从节点1
redis-slave-1:
image: redis:7.0.4
container_name: redis-slave-1
ports:
- "6380:6379" # 从节点1端口,避免和主节点冲突
command: redis-server --requirepass 123456 --slaveof redis-master 6379 --masterauth 123456 --bind 0.0.0.0
# 核心配置:--slaveof 主节点容器名 主节点端口;--masterauth 主节点密码
volumes:
- ./slave1/data:/data
networks:
- redis-network
depends_on:
- redis-master # 依赖主节点,主节点启动后再启动从节点
# Redis 从节点2
redis-slave-2:
image: redis:7.0.4
container_name: redis-slave-2
ports:
- "6381:6379" # 从节点2端口
command: redis-server --requirepass 123456 --slaveof redis-master 6379 --masterauth 123456 --bind 0.0.0.0
volumes:
- ./slave2/data:/data
networks:
- redis-network
depends_on:
- redis-master
# 自定义网络,确保主从、哨兵能互相通信
networks:
redis-network:
driver: bridge
⚠️ 关键说明:
--bind 0.0.0.0:允许外部(包括容器内部)访问,避免哨兵连不上主从- 容器名固定为
redis-master、redis-slave-1、redis-slave-2,后续哨兵配置会用到 - 密码统一为
123456,可根据需求修改,但要保证主从、哨兵密码一致
3.3 启动主从集群
在 docker-compose.yml 所在目录(/docker/docker-master-slave/redis)执行:
docker-compose up -d
启动成功后,查看容器状态:
docker ps
若出现 3 个状态为 Up 的容器(redis-master、redis-slave-1、redis-slave-2),说明主从集群启动成功。
3.4 验证主从同步
进入主节点,写入数据,验证从节点是否能同步:
# 进入主节点容器
docker exec -it redis-master redis-cli -a 123456
# 写入测试数据
set test_key "redis-master-slave-test"
# 查看数据
get test_key
# 退出主节点
exit
进入任意一个从节点,查看是否能获取到主节点写入的数据:
# 进入从节点1
docker exec -it redis-slave-1 redis-cli -a 123456
# 查看主节点写入的数据(能获取到说明同步成功)
get test_key
# 尝试写入数据(从节点只读,会报错,正常现象)
set test_key2 "error" # 报错:(error) READONLY You can't write against a read only replica.
# 退出从节点
exit
✅ 主从同步验证成功,主从集群搭建完成。
⚠️ 常见报错:若从节点无法同步,检查主节点 command 中是否加了 --bind 0.0.0.0,以及从节点 --masterauth 是否和主节点密码一致。
四、搭建 Redis 哨兵集群(3 个哨兵)
哨兵的核心作用是监控主从集群,当主节点故障时,自动选举新主节点,实现故障转移。步骤如下:
4.1 创建哨兵目录结构
在主从目录的同级目录下,创建哨兵目录(路径:/docker/docker-master-slave/sentinel):
# 进入上级目录
cd /docker/docker-master-slave
# 创建哨兵目录
mkdir -p sentinel
# 进入哨兵目录
cd sentinel
4.2 编写哨兵配置文件(3 个)
哨兵需要至少 3 个实例才能实现投票选举,创建 3 个哨兵配置文件(sentinel1.conf、sentinel2.conf、sentinel3.conf),内容完全一致,仅文件名不同。
# 创建并编辑第一个哨兵配置文件
vi sentinel1.conf
复制以下内容到配置文件中(保存退出:按 Esc,输入 :wq):
protected-mode no # 关闭保护模式,允许外部访问
port 26379 # 哨兵端口(3个哨兵端口相同,容器内部不冲突)
sentinel monitor mymaster redis-master 6379 2 # 监控主节点(容器名redis-master,端口6379,2票同意即可故障转移)
sentinel down-after-milliseconds mymaster 5000 # 主节点5秒无响应,标记为下线
sentinel failover-timeout mymaster 60000 # 故障转移超时时间(60秒)
sentinel parallel-syncs mymaster 1 # 故障转移后,从节点同步新主节点的并发数
sentinel auth-pass mymaster 123456 # 主从节点的密码,和主从配置一致
复制上述配置文件,生成另外 2 个哨兵配置:
# 复制配置文件,生成sentinel2.conf和sentinel3.conf
cp sentinel1.conf sentinel2.conf
cp sentinel1.conf sentinel3.conf
⚠️ 避坑重点:sentinel monitor 后面的主节点必须写容器名 redis-master(不是 IP),因为主从和哨兵在同一个 Docker 网络,容器名可自动解析,避免 IP 变化导致哨兵连不上主节点。
4.3 编写哨兵 docker-compose.yml 文件
在哨兵目录(/docker/docker-master-slave/sentinel)下,创建 docker-compose.yml 文件:
version: '3.8'
services:
# 哨兵1
redis-sentinel-1:
image: redis:latest # 哨兵用latest版,兼容7.0+
container_name: redis-sentinel-1
ports:
- "26379:26379" # 哨兵1端口映射
command: redis-sentinel /usr/local/etc/redis/sentinel.conf # 启动哨兵,指定配置文件
volumes:
- ./sentinel1.conf:/usr/local/etc/redis/sentinel.conf # 挂载哨兵配置文件
networks:
- redis-network # 和主从用同一个网络,确保能通信
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2 # 依赖主从节点,主从启动后再启动哨兵
# 哨兵2
redis-sentinel-2:
image: redis:latest
container_name: redis-sentinel-2
ports:
- "26380:26379" # 哨兵2端口映射
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel2.conf:/usr/local/etc/redis/sentinel.conf
networks:
- redis-network
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2
# 哨兵3
redis-sentinel-3:
image: redis:latest
container_name: redis-sentinel-3
ports:
- "26381:26379" # 哨兵3端口映射
command: redis-sentinel /usr/local/etc/redis/sentinel.conf
volumes:
- ./sentinel3.conf:/usr/local/etc/redis/sentinel.conf
networks:
- redis-network
depends_on:
- redis-master
- redis-slave-1
- redis-slave-2
# 关联主从的网络,确保哨兵能访问主从节点
networks:
redis-network:
external: true # 引用外部网络(主从集群创建的网络)
⚠️ 关键说明:networks 中 redis-network 设为 external: true,必须和主从集群的网络名称一致,否则哨兵无法和主从通信。
4.4 启动哨兵集群
在哨兵目录(/docker/docker-master-slave/sentinel)下执行:
docker-compose up -d
启动成功后,查看哨兵容器状态:
docker ps
若出现 3 个状态为 Up 的哨兵容器(redis-sentinel-1/2/3),说明哨兵集群启动成功。
4.5 验证哨兵监控状态
进入任意一个哨兵容器,查看监控的主节点状态:
# 进入哨兵1容器
docker exec -it redis-sentinel-1 redis-cli -p 26379
# 查看主节点状态(核心命令)
sentinel master mymaster
若输出中包含以下内容,说明哨兵监控正常:
status=ok
ip=172.19.0.2 # 主节点内部IP(无需关注,正常现象)
port=6379
slaves=2 # 2个从节点,和我们搭建的一致
sentinels=3 # 3个哨兵,和我们搭建的一致
✅ 哨兵集群搭建完成,已成功监控主从集群。
⚠️ 常见报错:若出现 flags: s_down,master,disconnected(主节点下线、连接失败),大概率是防火墙拦截,执行以下命令关闭防火墙(测试环境):
systemctl stop firewalld
systemctl disable firewalld
生产环境可开放 6379(Redis)和 26379(哨兵)端口,无需关闭防火墙:
firewall-cmd --add-port=6379/tcp --permanent
firewall-cmd --add-port=26379/tcp --permanent
firewall-cmd --reload
五、测试故障转移(核心验证)
故障转移是哨兵的核心功能,我们手动停止主节点,验证哨兵是否能自动选举新主节点:
5.1 停止主节点容器
# 停止主节点(redis-master)
docker stop redis-master
5.2 查看哨兵日志,观察故障转移过程
# 查看哨兵1日志(实时输出)
docker compose logs -f redis-sentinel-1
日志中会出现以下关键信息(说明故障转移成功):
# 主节点标记为下线
+sdown master mymaster 172.19.0.2 6379
# 投票选举新主节点
+vote-for-leader xxxxx 1
# 切换主节点(从节点升级为新主节点)
+switch-master mymaster 172.19.0.2 6379 172.19.0.3 6379
5.3 验证新主节点状态
# 进入哨兵容器,查看主节点状态
docker exec -it redis-sentinel-1 redis-cli -p 26379
sentinel master mymaster
若输出中出现以下内容,说明故障转移成功:
- status=ok
- address=172.19.0.3:6379(原从节点 1 的内部 IP,已升级为新主节点)
- slaves=2(原主节点下线后,变为从节点,新主节点有 2 个从节点)
5.4 恢复原主节点(可选)
若想恢复原主节点,启动原主节点容器即可,哨兵会自动将其变为从节点,同步新主节点的数据:
docker start redis-master
再次查看主节点状态,会发现原主节点已变为从节点,新主节点仍为之前选举的从节点。
六、常见问题排查(避坑汇总)
本文汇总了实操中遇到的所有问题,新手可直接对照解决:
6.1 启动主从时,容器名冲突(Conflict. The container name "/redis-master" is already in use)
原因:之前启动过主从容器,未彻底删除,容器名被占用。解决方案:强制删除冲突容器,再重新启动:
docker rm -f redis-master redis-slave-1 redis-slave-2
6.2 哨兵连不上主节点(flags: s_down,master,disconnected)
原因:1. 防火墙拦截;2. 哨兵配置中主节点写的是 IP,不是容器名;3. 主从节点未加 --bind 0.0.0.0。解决方案:关闭防火墙(或开放端口),哨兵配置中主节点改为 redis-master,主从 command 加 --bind 0.0.0.0。
6.3 启动哨兵时,提示网络不存在(network redis-network not found)
原因:哨兵 docker-compose.yml 中引用的外部网络,主从集群未创建(或网络名称不一致)。解决方案:先启动主从集群,创建 redis-network 网络,再启动哨兵。
6.4 无法同时启动单机 Redis 和主从集群
原因:单机 Redis 和主从集群都用 6379 端口,端口冲突。解决方案:先停止其中一个,再启动另一个(停止主从用 docker compose down,停止单机用 docker stop redis)。
七、总结
本文从 Docker Compose 安装开始,一步步完成了 Redis 1 主 2 从 3 哨兵集群的搭建,包含主从同步验证、哨兵监控验证、故障转移测试,以及所有常见问题的解决方案。
核心要点:
- 主从和哨兵必须在同一个 Docker 网络,哨兵配置主节点用容器名,避免 IP 变化导致通信失败。
- 哨兵至少需要 3 个实例,才能实现投票选举,保证故障转移的可靠性。
- 主从、哨兵密码必须一致,否则会出现认证失败,无法同步或监控。
- 测试环境可关闭防火墙,生产环境建议开放对应端口,保证安全性。
更多推荐
所有评论(0)