使用Docker Compose部署基于Sentinel的高可用Redis集群

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群。

14692678677279

大家一定非常熟悉如何利用Docker启动单个Redis容器用于开发环境,本文将介绍如何利用Docker Compose模板在本机和云端部署基于Sentinel的高可用Redis 3集群。

Redis集群可以在一组redis节点之间实现高可用性和sharding。今天我们重点围绕master-slave的高可用模式来进行讨论,在集群中会有1个master和多个slave节点。当master节点失效时,应选举出一个slave节点作为新的master。然而Redis本身(包括它的很多客户端)没有实现自动故障发现并进行主备切换的能力,需要外部的监控方案来实现自动故障恢复。

Redis Sentinel是官方推荐的高可用性解决方案。它是Redis集群的监控管理工具,可以提供节点监控、通知、自动故障恢复和客户端配置发现服务。

今天我们的部署模型是 Redis Sentinel 介绍的实例二,也是实战中比较常见的一种部署模式:

14692659415657

本文所有示例代码都可以从 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集群的部署和故障恢复,但是这还不是一个分布式的高可用部署。我们下面会利用阿里云容器服务来进行验证

云端部署高可用Redis集群

阿里云容器服务 在兼容Docker Compose编排模板的基础上,做了大量的扩展。能够更好地帮助我们在Docker集群中部署分布式应用。

首先您需要创建一个包含至少三个节点的集群(否则您需要注释掉相应的"affinity:service"部署约束)

然后我们利用下面的 docker compose模板部署高可用Redis集群

master:
  image: redis:3
  environment:
    - affinity:service!=slave
  restart: always
slave:
  image: redis:3
  command: redis-server --slaveof redis-master 6379
  environment:
    - affinity:service!=master
    - affinity:service!=slave
  labels: 
    aliyun.scale: "2"
  restart: always
  links:
    - master:redis-master
sentinel:
  image: registry.aliyuncs.com/acs-sample/redis-sentinel:3
  environment:
    - affinity:service!=sentinel
  labels: 
    aliyun.scale: "3"
  restart: always
  links:
    - master:redis-master
    - slave

这里使用了预编译的sentinel镜像"registry.aliyuncs.com/acs-sample/redis-sentinel:3"

更重要是,引入了一些阿里云扩展使得对分布式应用更好地控制容器在宿主机节点的部署

  • aliyun.scale 标签:描述了服务的实例数量
  • affinity:service 环境变量描述了服务的部署约束:比如对于Redis slave而言,我们不希望在一个宿主机节点上同时部署master和slave,或多个slave,我们可以方便用示例中的方法描述这些约束。

关于这些的详尽解释请参见帮助文档

一键部署之后,我们就已经有一个真正高可用的Redis集群了

  1. 在这里master和2个slave部署到不同的宿主机节点中
  2. 3个sentinel部署到不同的宿主机节点中
    这样任何一个宿主机节点失效,都不会导致Redis集群失败

14692757591755

总结

文章介绍了如何在本地部署一个Redis集群,并利用Redis Sentinel实现自动化的主从切换。并在此基础上利用阿里云容器服务扩展,一键部署一个真正的高可用分布式Redis集群。

对于Redis而言,阿里云提供了云数据库 Redis 版,对于大部分对SLA有要求的客户我们建议在生产环境使用Redis云服务。但是如果大家对版本、配置有特殊要求的时候,使用Docker部署Redis也是非常方便的。

出于性能考虑,在Docker容器中运行Redis不建议采用bridge网络对外提供访问,如需对外部VM或应用提供服务建议采用host网络模式,并注意安全保护;如果只是对集群中容器提供redis访问,则容器服务默认提供的跨宿主机容器网络会提供优化而安全的网络配置。同时建议在Docker容器设置中,给Redis容器配置合适的内存设置。

本文也给大家提供了一个示例,如何采用Docker的方式开发分布式应用并在云端部署生产级别环境。阿里云容器服务不但支持docker-compose模板提供的容器功能,使得本地开发的Docker镜像和编排模板可以轻松上云;更提供了灵活的部署约束描述,使得对分布式应用的部署和控制变得非常方便。

想了解更多容器服务内容,请访问 https://www.aliyun.com/product/containerservice

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore     ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库 ECS 实例和一台目标数据库 RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
目录
相关文章
|
5天前
|
存储 Cloud Native 文件存储
云原生之使用Docker部署home-page个人导航页
【5月更文挑战第4天】云原生之使用Docker部署home-page个人导航页
19 1
|
1天前
|
Cloud Native 测试技术 数据安全/隐私保护
云原生之使用Docker部署Teedy轻量级文档管理系统
【5月更文挑战第8天】云原生之使用Docker部署Teedy轻量级文档管理系统
12 1
|
2天前
|
Cloud Native 测试技术 Linux
云原生之使用Docker部署homer静态主页
【5月更文挑战第7天】云原生之使用Docker部署homer静态主页
10 0
|
3天前
|
监控 Cloud Native 测试技术
云原生之使用Docker部署ServerBee服务器监控工具
【5月更文挑战第6天】云原生之使用Docker部署ServerBee服务器监控工具
12 1
|
4天前
|
前端开发 应用服务中间件 nginx
前后端分离项目Docker部署指南(下)
前后端分离项目Docker部署指南(下)
|
4天前
|
NoSQL 关系型数据库 网络安全
前后端分离项目Docker部署指南(上)
前后端分离项目Docker部署指南(上)
|
4天前
|
开发框架 安全 网络安全
【Docker 专栏】Docker 多平台应用构建与部署
【5月更文挑战第8天】Docker作为一种关键的容器化技术,简化了多平台应用的构建与部署。它提供一致的运行环境,确保应用在不同平台无缝运行;通过分层构建机制加速镜像创建,提升开发效率。Docker的可移植性、高效部署及资源利用率是其主要优势。流程包括开发环境准备、构建镜像、测试验证及部署。然而,面临操作系统差异、网络安全和资源限制等挑战,需注意安全、版本管理和性能优化。Docker在多平台场景的应用将持续发挥价值。
【Docker 专栏】Docker 多平台应用构建与部署
|
5天前
|
存储 关系型数据库 Linux
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
CentOS如何使用Docker部署Plik服务并实现公网访问本地设备上传下载文件
27 4
|
5天前
|
数据可视化 Linux Docker
如何使用Docker部署Dashy并无公网ip远程访问管理界面
如何使用Docker部署Dashy并无公网ip远程访问管理界面
5 0
|
5天前
|
NoSQL Unix MongoDB
【docker 】docker-compose 部署mongoDB
【docker 】docker-compose 部署mongoDB
11 1