1. Redis Sentinel 简介
Redis Sentinel 是 Redis 高可用解决方案的一部分。它提供了监控、通知和自动故障转移功能,确保 Redis 集群在主节点发生故障时仍然可以继续工作。以下是 Redis Sentinel 的主要功能和作用:
监控: Sentinel 会不断检查每个 Redis 主节点和从节点的运行状态,以确保它们正常工作。
通知: 如果 Redis 实例出现故障,Sentinel 会通知系统管理员或其他应用程序,告知故障情况。
自动故障转移: 当主节点发生故障时,Sentinel 会将其中一个从节点提升为新的主节点,并通知其他从节点更新它们的配置,从而完成故障转移。
**配置提供者:**Sentinel 可以作为客户端的配置提供者,向客户端提供当前主节点的信息,以确保客户端能够始终连接到主节点。
2. Sentinel 配置示例
以下是一个典型的 Sentinel 配置文件示例:
port 26379
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster yourpassword
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
port 26379
:指定 Sentinel 监听的端口。sentinel monitor mymaster 127.0.0.1 6379 2
:mymaster
是主节点的名称,可以自定义。127.0.0.1
是主节点的 IP 地址或主机名。6379
是主节点的端口。2
是 Sentinel 判断主节点失效所需的最小 Sentinel 数量。
sentinel auth-pass mymaster yourpassword
:设置访问主节点的密码。sentinel down-after-milliseconds mymaster 5000
:如果主节点在 5000 毫秒内没有响应,Sentinel 会认为它已下线。sentinel parallel-syncs mymaster 1
:在故障转移期间,同时可以有多少个从节点与新的主节点进行同步。sentinel failover-timeout mymaster 60000
:设置故障转移操作的超时时间为 60000 毫秒。
3. 使用 Docker 和 Docker Compose 来配置 Redis 哨兵模式
1. 创建目录结构
redis-sentinel/
├── docker-compose.yml
├── master/
│ ├── redis.conf
├── slave1/
│ ├── redis.conf
├── slave2/
│ ├── redis.conf
├── sentinel/
├── sentinel.conf
2. 配置 Redis 主服务器和从服务器
在 master/redis.conf
中配置主服务器:
port 6379
bind 0.0.0.0
daemonize no
requirepass m123456
save 900 1
save 300 10
save 60 10000
dir /data
appendonly yes
appendfilename "myappendonly.aof"
appendfsync everysec
dbfilename mydump.rdb
在 slave1/redis.conf
和 slave2/redis.conf
中配置从服务器:
port 6379
bind 0.0.0.0
daemonize no
requirepass m123456
save 900 1
save 300 10
save 60 10000
dir /data
appendonly yes
appendfilename "myappendonly.aof"
appendfsync everysec
dbfilename mydump.rdb
replicaof redis-master 6379
masterauth m123456
3. 配置 Redis 哨兵
在 sentinel/sentinel.conf
中配置哨兵:
port 26379
daemonize no
sentinel monitor mymaster 172.20.0.2 6379 2
sentinel auth-pass mymaster m123456
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 60000
4. 创建 docker-compose.yml
编写 docker-compose.yml
文件:
version: '3.3'
services:
redis-master:
image: redis:latest
container_name: redis-master
hostname: redis-master
ports:
- "8001:6379"
volumes:
./master/redis.conf:/usr/local/etc/redis/redis.conf
./master/data:/data
networks:
redis-network:
ipv4_address: 172.20.0.2
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-slave1:
image: redis:latest
container_name: redis-slave1
hostname: redis-slave1
depends_on:
- redis-master
ports:
- "8002:6379"
volumes:
./slave1/redis.conf:/usr/local/etc/redis/redis.conf
./slave1/data:/data
networks:
redis-network:
ipv4_address: 172.20.0.3
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
redis-slave2:
image: redis:latest
container_name: redis-slave2
hostname: redis-slave2
depends_on:
- redis-master
ports:
- "8003:6379"
volumes:
./slave2/redis.conf:/usr/local/etc/redis/redis.conf
./slave2/data:/data
networks:
redis-network:
ipv4_address: 172.20.0.4
command: ["redis-server", "/usr/local/etc/redis/redis.conf"]
sentinel1:
image: redis:latest
container_name: redis-sentinel1
hostname: redis-sentinel1
depends_on:
redis-master
redis-slave1
redis-slave2
ports:
- "26379:26379"
volumes:
- ./sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
networks:
redis-network:
ipv4_address: 172.20.0.5
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
sentinel2:
image: redis:latest
container_name: redis-sentinel2
hostname: redis-sentinel2
depends_on:
redis-master
redis-slave1
redis-slave2
ports:
- "26380:26379"
volumes:
- ./sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
networks:
redis-network:
ipv4_address: 172.20.0.6
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
sentinel3:
image: redis:latest
container_name: redis-sentinel3
hostname: redis-sentinel3
depends_on:
redis-master
redis-slave1
redis-slave2
ports:
- "26381:26379"
volumes:
- ./sentinel/sentinel.conf:/usr/local/etc/redis/sentinel.conf
networks:
redis-network:
ipv4_address: 172.20.0.7
command: ["redis-sentinel", "/usr/local/etc/redis/sentinel.conf"]
networks:
redis-network:
driver: bridge
ipam:
config:
- subnet: 172.20.0.0/16
5. 启动服务
在 redis-sentinel
目录下,运行以下命令启动 Redis 和 Sentinel 服务:
[root@icoolkj redis-sentinel]# docker-compose up -d
Creating network "redis-sentinel_redis-network" with driver "bridge"
Creating redis-master ... done
Creating redis-slave1 ... done
Creating redis-slave2 ... done
Creating redis-sentinel2 ... done
Creating redis-sentinel3 ... done
Creating redis-sentinel1 ... done
6. 检查服务状态
确保所有容器都已启动并正常运行:
[root@icoolkj redis-sentinel]# docker-compose ps
Name Command State Ports
redis-master docker-entrypoint.sh redis ... Up 0.0.0.0:8001->6379/tcp
redis-sentinel1 docker-entrypoint.sh redis ... Up 0.0.0.0:26379->26379/tcp, 6379/tcp
redis-sentinel2 docker-entrypoint.sh redis ... Up 0.0.0.0:26380->26379/tcp, 6379/tcp
redis-sentinel3 docker-entrypoint.sh redis ... Up 0.0.0.0:26381->26379/tcp, 6379/tcp
redis-slave1 docker-entrypoint.sh redis ... Up 0.0.0.0:8002->6379/tcp
redis-slave2 docker-entrypoint.sh redis ... Up 0.0.0.0:8003->6379/tcp
[root@icoolkj redis-sentinel]#
7. 测试哨兵模式
可以通过停止 Redis 主服务器来测试哨兵模式:
[root@icoolkj redis-sentinel]# docker stop redis-master
redis-master
[root@icoolkj redis-sentinel]#
此时,哨兵应该会检测到主服务器故障并将其中一个从服务器提升为新的主服务器。可以通过查看哨兵日志来确认故障转移是否成功:
[root@icoolkj redis-sentinel]# docker logs redis-sentinel1
......
1:X 08 Aug 2024 00:29:30.783 * +slave slave 172.20.0.2:6379 172.20.0.2 6379 @ mymaster 172.20.0.4 6379
1:X 08 Aug 2024 00:29:30.786 # Could not rename tmp config file (Device or resource busy)
1:X 08 Aug 2024 00:29:30.786 # WARNING: Sentinel was not able to save the new configuration on disk!!!: Device or resource busy
1:X 08 Aug 2024 00:29:35.831 # +sdown slave 172.20.0.2:6379 172.20.0.2 6379 @ mymaster 172.20.0.4 6379
[root@icoolkj redis-sentinel]#
8. 配置持久化数据和日志
确保 Redis 数据和日志被持久化到本地,以防止容器重启时数据丢失。在 docker-compose.yml
文件中已经配置了持久化卷:
volumes:
./master/data:/data
./master/log:/var/log/redis
同样的配置适用于从服务器和哨兵。
这样,你就完成了使用 Docker Compose 配置 Redis 哨兵模式的步骤,并确保了数据和日志的持久化。
===============================================
4. 常见问题
1. 查看容器日志以诊断问题
[root@icoolkj redis-sentinel]# docker-compose logs redis-slave1
......
redis-slave1 | 1:S 08 Aug 2024 00:42:42.019 * 1 changes in 900 seconds. Saving...
redis-slave1 | 1:S 08 Aug 2024 00:42:42.020 * Background saving started by pid 22
redis-slave1 | 22:C 08 Aug 2024 00:42:42.024 * DB saved on disk
redis-slave1 | 22:C 08 Aug 2024 00:42:42.024 * RDB: 2 MB of memory used by copy-on-write
redis-slave1 | 1:S 08 Aug 2024 00:42:42.121 * Background saving terminated with success
[root@icoolkj redis-sentinel]#
2. 使用 docker inspect
查询容器的详细信息,并使用 grep
过滤网络信息
[root@icoolkj ~]# docker inspect redis-sentinel1 | grep -A 10 "Networks"
"Networks": {
"redis-sentinel_redis-network": {
"IPAMConfig": {
"IPv4Address": "172.20.0.5"
},
"Links": null,
"Aliases": [
"sentinel1"
],
"MacAddress": "02:42:ac:14:00:05",
"NetworkID": "4c51ec0fd3d5c080f3b2414a87e2c029eed2bef88223d9983e4d6d6ac73dc9cc",
[root@icoolkj ~]#
3. 遇到 Redis Sentinel 无法解析 redis-master
主机名的问题时
在 Sentinel 配置文件 sentinel.conf
中使用静态 IP 地址,而不是主机名。例如:
port 26379
daemonize no
sentinel monitor mymaster 172.20.0.2 6379 2