前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >基于consul的Redis高可用方案

基于consul的Redis高可用方案

作者头像
用户1278550
发布2018-08-09 14:19:22
2.8K0
发布2018-08-09 14:19:22
举报
文章被收录于专栏:idbaidba

一 前言

这几天在研究如何做Redis的高可用容灾方案,查询了资料和咨询DBA同行,了解到Redis可以基于consul和sentinel实现读写分离以及HA高可用方案。本文讲述基于consul的Redis高可用方案实践。

感谢邓亚运的提示和资料协助。

二 consul 是什么?

Consul是HashiCorp公司基于go语言研发用于服务发现和配置共享开的分布式高可用的系统。提供内服务注册与发现框架,分布一致性协议实现,健康检查,Key/Value存储,多数据中心方案,以及Web UI支持,相比于Zookeeper,Consul不再需要依赖其他工具。

Consul提供的如下关键特性:

  1. Consul采用Raft一致性协议算法来保证服务的高可用,使用GOSSIP协议管理成员和广播消息,并且支持ACL访问控制。
  2. 服务注册与发现: Consul 同时支持DNS或者HTTP两种接口进行服务注册和服务发现。
  3. 支持健康检查: Consul可以通过定期运行脚本进行健康检查,根据脚本的返回值判断机器或服务是否健康,返回值为0时才代表健康。用户可以自定义的任意shell/Python脚本进行服务(Redis/MySQL等)的健康检查,这点相比其他同类工具更灵活。值得注意的是consul中返回值0是没问题(passed),1是警告(warning),其他值是检查失败(critical)
  4. Key/Value存储: 一个用来存储动态配置的系统。提供简单的HTTP接口,可以在任何地方操作。
  5. 支持多数据中心方案:支持多机房配置,可以避免单机房单点故障,多个数据中心要求每个数据中心都要安装一组Consul cluster,多个数据中心间基于gossip protocol协议来通讯,使用Raft算法实现一致性。
  6. 简易安装部署:安装包仅包含一个二进制文件,支持跨平台(*Nix,WIN)运行。可与Docker等轻量级容器实现无缝配合。
  7. 官方提供web管理界面, etcd无此功能.

三 Consul 架构组成

Consul是分布式的高可用系统,该系统中有两种角色Server 和Client。通过启动agent时指定Server或者client模式实现Consul集群中角色划分。

Consul Server:服务端用于保存Consul Cluster的状态信息, 实现数据一致性,响应RPC请求。在局域网内与本地客户端通讯, 通过广域网与其他数据中心通讯。每个Consul Cluster的Server数量推荐为3或5个。

Consul Client:客户端,只维护自身的状态, 并将HTTP和DNS接口请求转发给服务端。

注意:

Server和Client的角色和Consul Cluster上运行的应用服务无关, 是基于Consul层面的一种角色划分。

四 Consul和同类工具的对比表

五 如何使用

环境准备

代码语言:javascript
复制
server: 10.9.51.13 
client: 10.215.20.13 10.215.20.7 10.9.141.52
  1. 下载和安装 wget "https://releases.hashicorp.com/consul/1.0.7/consul_1.0.7_linux_amd64.zip" 如果前面的特性介绍所说,consul其实就是一个二进制文件,下载以后解压放到/usr/local/bin之后就可以使用,不依赖任何东西。 cp consul /usr/local/bin/
  2. 初始化目录 mkdir /etc/consul.d/ -p && mkdir /data/consul/shell -p vim /etc/consul.d/client.json
  3. 配置文件 在server 节点 10.9.51.13 编辑配置文件 /etc/consul.d/server.json { "data_dir": "/data/consul", "datacenter": "dc1", "log_level": "INFO", "server": true, "bootstrap_expect": 1, "bind_addr": "10.9.51.13", "client_addr": "10.9.51.13", "ui":true } 在三个client节点配置文件 /etc/consul.d/client.json { "data_dir": "/data/consul", "enable_script_checks": true, "bind_addr": "10.215.20.13", "retry_join": ["10.9.51.13"], "retry_interval": "15s", "rejoin_after_leave": true, "start_join": ["10.9.51.13"] } 其中bind_addr 是client 节点的ip地址, retry_join和start_join是server节点的ip地址。
  4. 启动server和client节点 先启动server节点 nohup consul agent -config-dir=/etc/consul.d > /data/consul/consul.log &

再分别启动三个client节点 nohup consul agent -config-dir=/etc/consul.d > /data/consul/consul.log &

2018/05/04 12:02:23 [INFO] agent: Join LAN completed. Synced with 1 initial agents 说明client节点已经加入到了consul集群。

  1. 查看各个节点的状态 consul members

consul operator raft list-peers Node ID Address State Voter RaftProtocol qabb-rdsa0 93b8e2a9-1ae1-3726-2993-c4f068ffd9b4 10.9.51.13:8300 leader true 3

  1. 通过 server节点 10.9.51.13:8500/ui 查看web ui

现在 qabb-r1db13 qabb-r1db7 上还没部署服务,所以显示为0个服务。接下来我们开始部署redis服务,构建基于Consul的Redis的高可用架构

六 基于Consul的Redis 高可用架构

Redis现有高可用架构sentinel遇到的问题

  1. Redis 哨兵架构下,服务器节点部署了哨兵,但业务部门没有在应用程序层面使用jedis哨兵驱动来自动发现Redis master,而使用直连IP master。当master挂掉,其他redis节点担当新master后,应用需要手工修改配置指向新master。
  2. Redis 客户端驱动还没有读写分离的配置,若想slave的读负载均衡,暂时没好的办法。

Consul 可以满足以上需求,配置两个DNS服务,一个是master的写服务,利用consul自身的服务健康检查和探测功能,自动发现新的master。 然后定义一个slave的读服务,基于DNS本身,能够对slave角色的redis IP做轮询,实现负载均衡的效果。

环境搭建

其实首先我们要在搭建一主两从的redis集群,因为本文是模拟练习,所以在client节点上部署。具体搭建过程省略,Redis的主从配置如下

代码语言:javascript
复制
 master 10.215.20.13:6380

 slave  10.215.20.7:6380 
        10.9.141.52:6380
定义服务配置文件

我们需要在每个client节点的/etc/consul.d/下面服务配置文件如下:

代码语言:javascript
复制
$ ll
total 12
-rw-r--r-- 1 root root 217 May  4 18:54 client.json
-rw-r--r-- 1 root root 317 May  4 18:55 r-6380-redis-test.json
-rw-r--r-- 1 root root 320 May  4 18:54 w-6380-redis-test.json

redis 主节点的服务定义配置文件 W-6380-redis-test.json

代码语言:javascript
复制
{
  "services": [
    {
      "name": "w-6380-redis-test",
      "tags": [
        "master-test-6380"
      ],
      "address": "10.215.20.13",
      "port": 6380,
      "checks": [
        {
          "args":["sh","-c","/data/consul/shell/check_redis_master.sh 6380 "],
          "interval": "15s"
        }
      ]
    }
  ]
}

redis 从节点的服务定义配置文件 r-6380-redis-test.json

代码语言:javascript
复制
{
  "services": [
    {
      "name": "r-6380-redis-test",
      "tags": [
        "slave-test-6380"
      ],
      "address": "10.215.20.7",
      "port": 6380,
      "checks": [
        {
          "args": ["sh","-c","/data/consul/shell/check_redis_slave.sh 6380 "],
          "interval": "10s"
        }
      ]
    }
  ]
}

关于服务的定义文件这里做简单说明:

Consul 默认会根据names的值定义DNS域名,默认以 .service.consul 结尾。不过我们可以利用domain参数修改。

根据上面的Redis主从服务定义配置文件,Consul client节点向server集群注册后,对应有两个域名:

w-6380-redis-test.service.consul 对应Redis master服务器ip。

r-6380-redis-test.service.consul 对应两个slave服务器ip,客户端发送请求时DNS轮训随机分配一个slave ip。

其中"args": ["sh","-c","/data/consul/shell/checkredisslave.sh 6380 "]代表对redis 6380 端口进行健康检查,如果异常返回2,consul client 会通知server端对异常服务进行服务治理。

动态加载配置

此时我们检查web-ui,

检查dns 配置

dig @10.9.51.13 -p 8600 w-6380-redis-test.service.consul

显示 10.215.20.13 对应于 w-6380-redis-test.service.consul

dig @10.9.51.13 -p 8600 r-6380-redis-test.service.consul

显示2个slave ip 10.215.20.7 ,10.9.141.52 对应 r-6380-redis-test.service.consul.

注意因为是测试,dns配置并未在我们公司的dns 域名服务器器做解析,所以日志中提示

;; WARNING: recursion requested but not available

切换演练

我们需要做2种容灾演练

  1. 读写分离,如一个slave (10.215.20.13:6380)挂了之后,观察系统的表现

继续关闭其他redis slave (10.9.141.52:6380)实例

可以看到结果符合预期: 当多个从库依次关闭,dns域名后端ip发生变化,会逐步剔除关闭的实例对应的ip,所有的slave关闭之后,域名r-6380-redis-test.service.consul 后端的ip指定到redis master对应的ip上。

  1. 配合sentinel,实现高可用,master挂了之后,观察系统的表现 在这里我选择consul集群中的server节点部署了sentinel监控,(生产中要3或者5个节点,测试过程只是部署一个)。模拟redis 主库 10.215.20.13:6380 crash。 127.0.0.1:6380> shutdown Sentinel 监控日志显示选举从库 10.215.20.7:6380 为主库。

此时我们再检查dns 域名 主库对应的dns域名 w-6380-redis-test.service.consul.对应ip已经变为10.215.20.7

r-6380-redis-test.service.consul. 对应的ip 减少了一个,变为10.9.141.52。

从目前的结果来看 切换符合预期。 另外说一下不符合预期的地方,在老的master 重新起来之后,sentinel会将老的master设置为新的slave,但是Consul 对应的dns 并未及时更新准确,需要执行consul reload 才可以。

生产过程中要注意这点,切换之后及时更新DNS缓存。

总结

从环境搭建以及测试结果来看,Consul这款工具使用起来十分简便,配合Redis sentinel 切换速度符合预期,上线生产环境时需要注意dns缓存时间的配置,以及DNS域名管理方面的支持。另外更多的技术知识点还是要多阅读Consul官方文档。

推荐阅读

  1. 本文实践参考邓亚运的文章,也推荐给大家看看http://www.cnblogs.com/gomysql/p/8010552.html
  2. Consul DNS接口相关说明 https://www.consul.io/docs/agent/dns.html
  3. 关于check用法请参考 https://www.consul.io/docs/agent/checks.html 0.92版本之后有很多改变。
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-05-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 前言
  • 二 consul 是什么?
  • 三 Consul 架构组成
  • 四 Consul和同类工具的对比表
  • 五 如何使用
  • 六 基于Consul的Redis 高可用架构
    • 环境搭建
      • 定义服务配置文件
    • 动态加载配置
      • 检查dns 配置
        • 切换演练
        • 总结
        • 推荐阅读
        相关产品与服务
        云数据库 Redis
        腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档