大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群。
Redis集群可以在一组redis节点之间实现高可用性和sharding。今天我们重点围绕master-slave的高可用模式来进行讨论,在集群中会有1个master和多个slave节点。当master节点失效时,应选举出一个slave节点作为新的master。然而Redis本身(包括它的很多客户端)没有实现自动故障发现并进行主备切换的能力,需要外部的监控方案来实现自动故障恢复。
Redis Sentinel是官方推荐的高可用性解决方案。它是Redis集群的监控管理工具,可以提供节点监控、通知、自动故障恢复和客户端配置发现服务。
今天我们的部署模型是 Redis Sentinel 介绍的实例二,也是实战中比较常见的一种部署模式:
本文所有示例代码都可以从 https://github.com/AliyunContainerService/redis-cluster 获得
本文采用的Redis镜像全部基于Docker提供的Redis官方镜像3.2.1
单机部署Redis集群
下面的测试需要本地环境已经安装Docker Engine和Docker Compose,推荐使用Docker for Mac/Windows。想在云端部署的同学可以直接跳到下一节
下载代码
git clone https://github.com/AliyunContainerService/redis-cluster
cd redis-cluster
目录下面的docker-compose.yml
模板定义Redis集群的服务组成
master:
image: redis:3
slave:
image: redis:3
command: redis-server --slaveof redis-master 6379
links:
- master:redis-master
sentinel:
build: sentinel
environment:
- SENTINEL_DOWN_AFTER=5000
- SENTINEL_FAILOVER=5000
links:
- master:redis-master
- slave
在模板中定义了下面一系列服务
- master: Redis master
- slave: Redis slave
- sentinel: Redis Sentinel
其中sentinel服务的Docker镜像是由 “./sentinel” 目录中的Dockerfile构建完成,只是在官方Redis镜像上添加了sentinel.conf
配置文件,并以sentinel模式启动容器。其配置文件如下,其中包含了sentinel对名为”mymaster”的集群的监控配置:
sentinel monitor mymaster redis-master 6379 2
sentinel down-after-milliseconds mymaster 5000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 5000
细节请参见sentinel.conf
配置自身。
注意:
- slave和sentinel容器初始化配置的Redis master节点主机名为”redis-master”,这里我们利用了Docker容器连接的别名机制来连接master和sentinel/slave容器实例
- 由于我们会部署3个Sentinel,我们把sentinel的”quorum”设置为2,只有两个sentinel同意故障切换,才会真正切换相应的redis master节点。
下面我们先构建 sentinel 服务所需 Docker image
docker-compose build
一键部署并启动Redis集群
docker-compose up -d
这时我们可以检查集群状态,应该是包含3个容器,1个master, 1个slave,和1个sentinel
docker-compose ps
显示结果如下
Name Command State Ports
--------------------------------------------------------------------------------------
rediscluster_master_1 docker-entrypoint.sh redis ... Up 6379/tcp
rediscluster_sentinel_1 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp
rediscluster_slave_1 docker-entrypoint.sh redis ... Up 6379/tcp
我们可以伸缩sentinel的实例数量到3个
docker-compose scale sentinel=3
伸缩slave的实例数量到2个,这样我们就有3个redis实例了(包含一个master)
docker-compose scale slave=2
检查集群状态,结果如下
docker-compose ps
Name Command State Ports
--------------------------------------------------------------------------------------
rediscluster_master_1 docker-entrypoint.sh redis ... Up 6379/tcp
rediscluster_sentinel_1 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp
rediscluster_sentinel_2 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp
rediscluster_sentinel_3 docker-entrypoint.sh redis ... Up 26379/tcp, 6379/tcp
rediscluster_slave_1 docker-entrypoint.sh redis ... Up 6379/tcp
rediscluster_slave_2 docker-entrypoint.sh redis ... Up 6379/tcp
我们可以利用下面的测试脚本来模拟master节点失效,并验证Redis集群的自动主从切换。
./test.sh
这个测试脚本实际上利用 docker pause
命令将 Redis master容器暂停,sentinel会发现这个故障并将master切换到其他一个备用的slave上面。
执行结果如下
Redis master: 172.17.0.2
Redis Slave: 172.17.0.3
------------------------------------------------
Initial status of sentinel
------------------------------------------------
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.2:6379,slaves=2,sentinels=3
Current master is
172.17.0.2
6379
------------------------------------------------
Stop redis master
rediscluster_master_1
Wait for 10 seconds
Current infomation of sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3
Current master is
172.17.0.3
6379
------------------------------------------------
Restart Redis master
rediscluster_master_1
Current infomation of sentinel
# Sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=172.17.0.3:6379,slaves=2,sentinels=3
Current master is
172.17.0.3
6379
我们可以利用Docker Compose方便地在本地验证Redis集群的部署和故障恢复