几个月没有更新博客了,已经长草了,特意来除草。本次主要分享如何利用consul来实现redis以及mysql的高可用。以前的公司mysql是单机单实例,高可用MHA加vip就能搞定,新公司mysql是单机多实例,那么显然这个方案不适用,后来也实现了故障切换调用dns api来修改域名记录,但是还是没有利用consul来实现高可用方便,后面会说明优势。redis单机多实例最正常不过了,那么redis单机多实例高可用也不太好做,当然也可以利用sentinel来实现,当failover以后调用脚本调用dns api修改域名解析也是可以的。也不是那么的优雅,有人会说怎么不用codis,redis cluster,这些方案固然好,但不适合我们,这些方案不够灵活,不能很好的处理热点数据的问题。那么consul是什么呢,接下慢慢说:
consul是HashiCorp公司(曾经开发过vgrant) 推出的一款开源工具, 基于go语言开发, 轻量级, 用于实现分布式系统的服务发现与配置。 与其他类似产品相比, 提供更“一站式”的解决方案。 consul内置有KV存储, 服务注册/发现, 健康检查, HTTP+DNS API, Web UI等多种功能。官网: https://www.consul.io/其他同类服务发现与配置的主流开源产品有:zookeeper和ETCD。
consul的优势:
1. 支持多数据中心, 内外网的服务采用不同的端口进行监听。 多数据中心集群可以避免单数据中心的单点故障, zookeeper和 etcd 均不提供多数据中心功能的支持
2. 支持健康检查. etcd 不提供此功能.
3. 支持 http 和 dns 协议接口. zookeeper 的集成较为复杂,etcd 只支持 http 协议. 有DNS功能, 支持REST API
4. 官方提供web管理界面, etcd 无此功能.
5. 部署简单, 运维友好, 无依赖, go的二进制程序copy过来就能用了, 一个程序搞定, 可以结合ansible来推送。
Consul和其他服务发现工具的对比表:
Consul 架构和角色
1. Consul Cluster由部署和运行了Consul Agent的节点组成。 在Cluster中有两种角色:Server和 Client。
2. Server和Client的角色和Consul Cluster上运行的应用服务无关, 是基于Consul层面的一种角色划分.
3. Consul Server: 用于维护Consul Cluster的状态信息, 实现数据一致性, 响应RPC请求。官方建议是: 至少要运行3个或者3个以上的Consul Server。 多个server之中需要选举一个leader, 这个选举过程Consul基于Raft协议实现. 多个Server节点上的Consul数据信息保持强一致性。 在局域网内与本地客户端通讯,通过广域网与其他数据中心通讯。Consul Client: 只维护自身的状态, 并将HTTP和DNS接口请求转发给服务端。
4. Consul 支持多数据中心, 多个数据中心要求每个数据中心都要安装一组Consul cluster,多个数据中心间基于gossip protocol协议来通讯, 使用Raft算法实现一致性
基础知识就介绍这么多了,更加详细的可以参考官网。下面我们来搭建一下consul,以及如何利用consul实现redis以及mysql的高可用。
测试环境(生产环境consul server部署3个或者5个):
consul server:192.168.0.10
consul client:192.168.0.20,192.168.0.30,192.168.0.40
consul的安装非常容易,从https://www.consul.io/downloads.html这里下载以后,解压即可使用,就是一个二进制文件,其他的都没有了。我这里使用的是0.92版本。文件下载以后解压放到/usr/local/bin。就可以使用了。不依赖任何东西。上面的4台服务器都安装。
4台机器都创建目录,分别是放配置文件,以及存放数据的。以及存放redis,mysql的健康检查脚本
mkdir /etc/consul.d/ -p && mkdir /data/consul/ -p
mkidr /data/consul/shell -p
然后把相关配置参数写入配置文件,其实也可以不用写,直接跟在命令后面就行,那样不方便管理。
consul server(192.168.0.10)配置文件(具体参数的意思请查询官网或者文章给的参考链接):
[root@db-server-yayun-01 ~]# cat /etc/consul.d/server.json
{
"data_dir": "/data/consul",
"datacenter": "dc1",
"log_level": "INFO",
"server": true,
"bootstrap_expect": 1,
"bind_addr": "192.168.0.10",
"client_addr": "192.168.0.10",
"ui":true
}
[root@db-server-yayun-01 ~]#
consul client(192.168.0.20,192.168.0.30,192.168.0.40)
[root@db-server-yayun-02 ~]# cat /etc/consul.d/client.json
{
"data_dir": "/data/consul",
"enable_script_checks": true,
"bind_addr": "192.168.0.20",
"retry_join": ["192.168.0.10"],
"retry_interval": "30s",
"rejoin_after_leave": true,
"start_join": ["192.168.0.10"]
}
[root@db-server-yayun-02 ~]#
3台服务器的配置文件差异不大,唯一有区别的就是bind_addr地方,自行修改为你自己服务器的ip。我测试环境是虚拟机,有多快网卡,所以必须指定,否则可以绑定0.0.0.0。
下面我们先启动consul server:
nohup consul agent -config-dir=/etc/consul.d > /data/consul/consul.log &
查看日志:
[root@db-server-yayun-01 consul]# cat consul.log
==> WARNING: BootstrapExpect Mode is specified as 1; this is the same as Bootstrap mode.
==> WARNING: Bootstrap mode enabled! Do not enable unless necessary
==> Starting Consul agent...
==> Consul agent running!
Version: 'v0.9.2'
Node ID: '5e612623-ec5b-386c-19be-d38876a9a46f'
Node name: 'db-server-yayun-01'
Datacenter: 'dc1'
Server: true (bootstrap: true)
Client Addr: 192.168.0.10 (HTTP: 8500, HTTPS: -1, DNS: 8600)
Cluster Addr: 192.168.0.10 (LAN: 8301, WAN: 8302)
Gossip encrypt: false, RPC-TLS: false, TLS-Incoming: false
==> Log data will now stream in as it occurs:
2017/12/09 09:49:53 [INFO] raft: Initial configuration (index=1): [{Suffrage:Voter ID:192.168.0.10:8300 Address:192.168.0.10:8300}]
2017/12/09 09:49:53 [INFO] raft: Node at 192.168.0.10:8300 [Follower] entering Follower state (Leader: "")
2017/12/09 09:49:53 [INFO] serf: EventMemberJoin: db-server-yayun-01.dc1 192.168.0.10
2017/12/09 09:49:53 [INFO] serf: EventMemberJoin: db-server-yayun-01 192.168.0.10
2017/12/09 09:49:53 [INFO] agent: Started DNS server 192.168.0.10:8600 (udp)
2017/12/09 09:49:53 [INFO] consul: Adding LAN server db-server-yayun-01 (Addr: tcp/192.168.0.10:8300) (DC: dc1)
2017/12/09 09:49:53 [INFO] consul: Handled member-join event for server "db-server-yayun-01.dc1" in area "wan"
2017/12/09 09:49:53 [INFO] agent: Started DNS server 192.168.0.10:8600 (tcp)
2017/12/09 09:49:53 [INFO] agent: Started HTTP server on 192.168.0.10:8500
2017/12/09 09:50:00 [ERR] agent: failed to sync remote state: No cluster leader
2017/12/09 09:50:00 [WARN] raft: Heartbeat timeout from "" reached, starting election
2017/12/09 09:50:00 [INFO] raft: Node at 192.168.0.10:8300 [Candidate] entering Candidate state in term 2
2017/12/09 09:50:00 [INFO] raft: Election won. Tally: 1
2017/12/09 09:50:00 [INFO] raft: Node at 192.168.0.10:8300 [Leader] entering Leader state
2017/12/09 09:50:00 [INFO] consul: cluster leadership acquired
2017/12/09 09:50:00 [INFO] consul: New leader elected: db-server-yayun-01
2017/12/09 09:50:00 [INFO] consul: member 'db-server-yayun-01' joined, marking health alive
2017/12/09 09:50:03 [INFO] agent: Synced node info