文章目录
- 一、引言
- 二、环境准备
- 前提条件
- 目录结构
- 三、配置文件
- 1. 主节点配置文件 sentinel-master.conf
- 2. 从节点配置文件
- 3. 哨兵配置文件 sentinel.conf
- 4. Docker Compose 文件
- 四、启动 Docker Compose
- 五、验证哨兵机制
- 1. 检查主节点状态
- 2. 检查从节点状态
- 3. 检查哨兵状态
- 4. 测试故障转移
- 六、常见问题及解决方法
- 七、结论
- 八、参考资料
一、引言
Redis 是一个高性能的键值存储系统,广泛应用于缓存、消息队列等场景。为了提高系统的可用性和容错能力,Redis 提供了哨兵(Sentinel)机制。哨兵可以监控主节点和从节点的状态,并在主节点失效时自动进行故障转移。本文将详细介绍如何使用 Docker 搭建 Redis 哨兵环境,确保你的 Redis 集群在出现故障时能够自动恢复。
二、环境准备
前提条件
- 已安装 Docker 和 Docker Compose。
- 基本的 Docker 和 Redis 知识。
目录结构
假设我们在 redis-sentinel 目录下进行操作,目录结构如下:
redis-sentinel/
├── conf
│ ├── sentinel-master.conf
│ ├── sentinel-slave1.conf
│ ├── sentinel-slave2.conf
│ └── sentinel-slave3.conf
├── docker-compose.yml
├── sentinel1
│ └── sentinel.conf
├── sentinel2
│ └── sentinel.conf
└── sentinel3└── sentinel.conf
三、配置文件
1. 主节点配置文件 sentinel-master.conf
# 绑定 IP 地址
bind 0.0.0.0# 配置端口号
port 6379# 开启 AOF 持久化
appendonly yes# 设置密码
# requirepass your_master_password
2. 从节点配置文件
- sentinel-slave1.conf
# 绑定 IP 地址
bind 0.0.0.0# 配置端口号
port 6379# 开启 AOF 持久化
appendonly yes# 指定主节点的地址和端口
replicaof 172.30.1.2 6379# 设置密码(如果主节点设置了密码)
# masterauth your_master_password# 设置密码(可选)
# requirepass your_slave_password
- sentinel-slave2.conf
# 绑定 IP 地址,允许远程连接
bind 0.0.0.0# 配置端口号
port 6379# 开启 AOF 持久化(可选)
appendonly yes# 指定主节点的地址和端口
replicaof 172.30.1.2 6379# 设置密码(如果主节点设置了密码)
# masterauth your_master_password# 设置密码(可选)
# requirepass your_slave_password
- sentinel-slave3.conf
# 绑定 IP 地址,允许远程连接
bind 0.0.0.0# 配置端口号
port 6379# 开启 AOF 持久化(可选)
appendonly yes# 指定主节点的地址和端口
replicaof 172.30.1.2 6379# 设置密码(如果主节点设置了密码)
# masterauth your_master_password# 设置密码(可选)
# requirepass your_slave_password
3. 哨兵配置文件 sentinel.conf
# 哨兵端口号
port 26379# 哨兵监控的主节点信息 mymaster是哨兵监控的主节点名称,可以自定义
sentinel monitor redis-sentinel 172.30.1.2 6379 2# 哨兵的 quorum 数值,表示多少个哨兵节点认为主节点不可用时才进行故障转移
sentinel down-after-milliseconds redis-sentinel 5000# 故障转移超时时间
sentinel failover-timeout redis-sentinel 60000# 使用主机名解析
# sentinel resolve-hostnames yes# 使用主机名广播
# sentinel announce-hostnames yes# 主节点的密码(如果设置了密码)
# sentinel auth-pass redis-sentinel your_master_password# 哨兵之间的认证密码(可选)
# sentinel auth-pass sentinel your_sentinel_password
sentinel resolve-hostnames yes
:哨兵在报告主节点和从节点的地址时,会使用主机名而不是 IP 地址。
sentinel announce-hostnames yes
:哨兵在向其他哨兵或客户端报告自己的地址时,会使用主机名而不是 IP 地址。
4. Docker Compose 文件
version: '3.8'services:redis-master:image: redis:latestcontainer_name: redis-mastercommand: ["redis-server", "/etc/redis/redis.conf"]volumes:- ./conf/sentinel-master.conf:/etc/redis/redis.confnetworks:redis-sentinel:ipv4_address: 172.30.1.2ports:- "6389:6379"- "16389:16379"redis-slave1:image: redis:latestcontainer_name: redis-slave1command: ["redis-server", "/etc/redis/redis.conf"]volumes:- ./conf/sentinel-slave1.conf:/etc/redis/redis.confnetworks:redis-sentinel:ipv4_address: 172.30.1.3ports:- "6390:6379"- "16390:16379"depends_on:- redis-masterredis-slave2:image: redis:latestcontainer_name: redis-slave2command: ["redis-server", "/etc/redis/redis.conf"]volumes:- ./conf/sentinel-slave2.conf:/etc/redis/redis.confnetworks:redis-sentinel:ipv4_address: 172.30.1.4ports:- "6391:6379"- "16391:16379"depends_on:- redis-masterredis-slave3:image: redis:latestcontainer_name: redis-slave3command: ["redis-server", "/etc/redis/redis.conf"]volumes:- ./conf/sentinel-slave3.conf:/etc/redis/redis.confnetworks:redis-sentinel:ipv4_address: 172.30.1.5ports:- "6392:6379"- "16392:16379"depends_on:- redis-masterredis-sentinel1:image: redis:latestcontainer_name: redis-sentinel1command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]volumes:- ./sentinel1:/usr/local/etc/redisdepends_on:- redis-master- redis-slave1- redis-slave2- redis-slave3networks:redis-sentinel:ipv4_address: 172.30.1.11ports:- "26379:26379"redis-sentinel2:image: redis:latestcontainer_name: redis-sentinel2command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]volumes:- ./sentinel2:/usr/local/etc/redisdepends_on:- redis-master- redis-slave1- redis-slave2- redis-slave3networks:redis-sentinel:ipv4_address: 172.30.1.12ports:- "26380:26379"redis-sentinel3:image: redis:latestcontainer_name: redis-sentinel3command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]volumes:- ./sentinel3:/usr/local/etc/redisdepends_on:- redis-master- redis-slave1- redis-slave2- redis-slave3networks:redis-sentinel:ipv4_address: 172.30.1.13ports:- "26381:26379"networks:redis-sentinel:driver: bridgeipam:config:- subnet: 172.30.1.0/24
四、启动 Docker Compose
在 redis-sentinel 目录下运行以下命令来启动 Docker Compose:
docker-compose up -d
五、验证哨兵机制
1. 检查主节点状态
docker exec -it redis-master redis-cli -a your_master_password
info replication
你应该能看到 role:master 和 connected_slaves:2,表示有两个从节点连接。
2. 检查从节点状态
docker exec -it redis-slave1 redis-cli -a your_slave_password
info replication
你应该能看到 role:slave 和 master_host:redis-master,表示从节点已成功连接到主节点。
3. 检查哨兵状态
docker exec -it redis-sentinel1 redis-cli -p 26379
sentinel master redis-sentinel
你应该能看到主节点和从节点的信息,确认哨兵已经正确监控主从节点。
4. 测试故障转移
停止主节点:
docker stop redis-master
检查哨兵状态:
docker exec -it redis-sentinel1 redis-cli -p 26379
sentinel master redis-sentinel
你应该能看到新的主节点信息,确认哨兵已经成功进行了故障转移。
使用docker logs -f redis-sentinel1
查看哨兵节点的日志信息,也会有如下日志输出:
+switch-master redis-sentinel 172.30.1.4 6379 172.30.1.2 637
六、常见问题及解决方法
- Failed to resolve hostname
如果未使用固定IP,而是使用桥接方式的动态IP,可能会出现哨兵节点无法解析主节点服务名的情况,这跟docker的现象如下图:
解决方案
可以在哨兵节点的配置文件中开启如下配置:
# 绑定 IP 地址
bind 0.0.0.0# 使用主机名解析
# sentinel resolve-hostnames yes# 使用主机名广播
# sentinel announce-hostnames yes
docker桥接模式内置了DNS解析服务,它可以使用服务名直接相互访问,不用设置容器的具体ip,这样就避免了每次重新部署容器时ip发生变动造成的配置麻烦。这种方式很方便,但部分版本的redis内部对域名访问的支持并不稳定。
- Could not rename tmp config file (Device or resource busy)
Could not rename tmp config file (Device or resource busy)
Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
出现该问题的原因是redis sentinel(哨兵)会更改节点和哨兵的conf文件,这涉及文件权限问题。最简单的一种处理方案:挂载文件时,选择挂载conf文件所在的目录,而不直接挂载conf文件。
- Next failover delay: I will not start a failover before
原因待定,临时解决方案:去掉各节点配置文件中的密码信息。
七、结论
通过使用 Docker 搭建 Redis 哨兵环境,我们可以轻松地实现 Redis 集群的高可用性和故障恢复。本文详细介绍了如何在docker中配置主节点、从节点和哨兵节点,并提供了详细的步骤和示例。希望这篇文章对你有所帮助,如果你有任何问题或建议,欢迎留言交流。
八、参考资料
-
- WARNING: Sentinel was not able to save the new configuration on disk
-
- 使用docker部署redis哨兵(sentinel)时遇到的问题