头脑风暴
出于学习目的, 您可以很轻松地在 docker 环境下运行 Redis 的单个实例, 但是如果您需要在生产环境中运行它, 那么必须将 Redis 部署为 HA(High Avaliable) 模式.
Redis Sentinel 为 Redis 提供高可用性, 这意味着使用 Sentinel 可以创建 Redis HA 部署, 该部署可以在无需人工干预的情况下抵抗某些类型的故障.
Redis Sentinel 提供的主要功能是:
当主节点发生故障时, 它将自动选择一个备用节点并将其升级为主节点.
它是如何做到的, 它会定期检查 Redis 实例的运行状况和运行状况, 还会将新的主服务器通知给客户端和从服务器. 使用的是带有领导者选举算法的 gossip 协议.
Sentinel 还充当客户端发现的中心授权来源, 客户端连接到 Sentinel 以获取主节点的地址.
本文以自己的亲身经历, 使用 Docker-compose 搭建一个 Redis Sentinel 模型 (1:master-2:slave:3:sentinel)
Docker-compose 搭建 Redis Sentinel
Redis Sentinel 是针对原始 Master/Slave 模型而衍生的高可用模型.
我们为便于灵活部署, 先易后难, 先搭建 Redis Master/Slave 模型, 再搭建 Redis Sentinel 模型.
文件组织格式如下
Redis-sentinel
├── Redis
│ └── docker-compose.YAML
└── sentinel
├── docker-compose.YAML
├── sentinel1.conf
├── sentinel2.conf
├── sentinel3.conf
└── sentinel.conf
1. Master/Slave
进入 Redis 文件夹, 创建 docker-compose.YAML 文件,
下面的 Compose 文件设置了 1Master 2Slave
- version: '3'
- services:
- master:
- image: Redis
- container_name: Redis-master
- command: Redis-server --requirepass redis_pwd --masterauth redis_pwd
- ports:
- - 6380:6379
- slave1:
- image: Redis
- container_name: Redis-slave-1
- ports:
- - 6381:6379
- command: Redis-server --slaveof Redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
- slave2:
- image: Redis
- container_name: Redis-slave-2
- ports:
- - 6382:6379
- command: Redis-server --slaveof Redis-master 6379 --requirepass redis_pwd --masterauth redis_pwd
注意, 如果设置了 Redis 客户端访问密码 requirepass, 那么也要设置相同的副本集同步密码 masterauth.
另外我们后面使用哨兵模式能够完成故障转移, 现有的 Master 可能会变成 Slave, 故在当前 Master 容器中也要携带 masterauth 参数.
可在容器内使用 config get [Param] 命令验证
执行 docker-compose up -d 会产生 3 个 Redis 容器, 分别映射到宿主机 6380,6381,6382 端口, 默认连接在 Redis-default 网桥.
docker ps 输出如下:
- fe2eb7a5cce9 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6382->6379/tcp Redis-slave-2
- 4c280aa6dc09 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6381->6379/tcp Redis-slave-1
- 91b83143b7c1 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6380->6379/tcp Redis-master
- 2. Redis Sentinel
很明显我们即将搭建的 Sentinel 容器需要能访问到以上 3 个容器, 故需要在形成 Sentinel 容器时使用外置的 Redis-default 网桥 (Redis Master/Slave docker-compose 已经创建).
2.1 进入 sentinel 文件夹, 创建 docker-compose.YAML
- version: '3'
- services:
- sentinel1:
- image: Redis
- container_name: Redis-sentinel-1
- ports:
- - 26379:26379
- command: Redis-sentinel /usr/local/etc/Redis/sentinel.conf
- volumes:
- - ./sentinel1.conf:/usr/local/etc/Redis/sentinel.conf
- sentinel2:
- image: Redis
- container_name: Redis-sentinel-2
- ports:
- - 26380:26379
- command: Redis-sentinel /usr/local/etc/Redis/sentinel.conf
- volumes:
- - ./sentinel2.conf:/usr/local/etc/Redis/sentinel.conf
- sentinel3:
- image: Redis
- container_name: Redis-sentinel-3
- ports:
- - 26381:26379
- command: Redis-sentinel /usr/local/etc/Redis/sentinel.conf
- volumes:
- - ./sentinel3.conf:/usr/local/etc/Redis/sentinel.conf
- networks:
- default:
- external:
- name: redis_default
2.2 创建哨兵文件, 将如下内容拷贝进去:
- port 26379
- dir /tmp
- sentinel monitor mymaster 172.20.0.3 6379 2
- sentinel auth-pass mymaster redis_pwd
- sentinel down-after-milliseconds mymaster 30000
- sentinel parallel-syncs mymaster 1
- sentinel failover-timeout mymaster 180000
- sentinel deny-scripts-reconfig yes
注意, 以上 172.20.0.3 是之前 Redis Master/slave 启动之后 Master 节点的 IP, 通过 docker inspect [containerIP] 获取, 这里我们要配合设置 Master/Slave 访问密码.
2.3 将哨兵文件复制三份, Volume 进 Sentinel 容器
- sudo cp sentinel.conf sentinel1.conf
- sudo cp sentinel.conf sentinel2.conf
- sudo cp sentinel.conf sentinel3.conf
docker-compose up -d 生成 3 个 Sentinel 容器.
此时 docker ps 显示如下:
- 80f4b776f5dd Redis "docker-entrypoint.s..." 58 minutes ago Up 57 minutes 6379/tcp, 0.0.0.0:26380->26379/tcp Redis-sentinel-2
- 3a1bcdc06253 Redis "docker-entrypoint.s..." 58 minutes ago Up 57 minutes 6379/tcp, 0.0.0.0:26379->26379/tcp Redis-sentinel-1
- 3bada23b572e Redis "docker-entrypoint.s..." 58 minutes ago Up 57 minutes 6379/tcp, 0.0.0.0:26381->26379/tcp Redis-sentinel-3
- fe2eb7a5cce9 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6382->6379/tcp Redis-slave-2
- 4c280aa6dc09 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6381->6379/tcp Redis-slave-1
- 91b83143b7c1 Redis "docker-entrypoint.s..." 2 hours ago Up 2 hours 0.0.0.0:6380->6379/tcp Redis-master
验证
Master/Slave 副本集
进入 Master 容器, 确认两个 Slave 容器已经连接.
Redis Sentinel 进入其中一个 Sentinel 容器, 确认 Master,2 个 Slave, 另外 2 个 Sentinel
flags: master 表明 master 正常运作, 异常情况会显示 s-down,o-down
num-slaves: 侦测到 2 个 Slave 副本集
num-other-sentinels: 除此之外, 还有 2 个哨兵
Redis Sentinel 高可用
停止 master 容器, 等待 10s, 进入任意 sentinel 容器, 使用
sentinel master mymaster
命令观察主节点发生变化, 观察外挂的 Sentinel*.conf 主节点 IP 发生变化
总结输出
当初做这个部署, 曾经尝试采用阿里云的 Redis-sentinel docker-compose 方式, 发现其采用 docker-compose scale 生成多个 Sentinel 容器, 不能映射到宿主机端口, 导致外部 Redis 客户端无法定位 sentinel.
结合网上一些资料, 摸索出渐进式部署 && 共享网桥的方式部署 Redis Sentinel, 本人亲测有效.
项目开源地址如下, 大家可积极使用.
https://github.com/zaozaoniao/Redis-sentinel-with-docker-compose
来源: https://www.cnblogs.com/JulianHuang/p/12650721.html