介绍
一直以来, 我们并未在线上启用 masterha_manager 自动切换脚本, 主要因为在网络抖动(网线, 所属机柜交换机不稳定)的情况下并不能保证数据库真的不能访问. 比如重启检测脚本所在机器的网卡并不能说明数据库出了问题, 所以从这方面看我们不能仅通过一个点的检测就判断数据库不可访问.
幸好可以通过 consul(因为 consul 提供 dns 接口, 笔者更倾向于使用 consul, 而不是 etcd)集群的特性, 我们增加多点检测机制, 在 n 个集群的环境中, 有超过半数的检测点检测到数据库有问题, 我们就认为数据库不可访问, 这时则开始调用
masterha_manager脚本进行切换, 如下图所示:
<checkmysql> <checkmysql> <checkmysql>
| | |
+---------+ +---------+ +---------+
| consul1 | | consul2 | | consul3 |
+---------+ +---------+ +---------+
\ | /
\ | /
\ | /
\ | /
+----------------------+
| http api && acl |
+----------------------+
|
|
+----------------------+
| consul-template | ----> < mysqlxxx.tpl > ---> <mysqlxxx.conf>
+----------------------+
|
+--------------------------+
| masterha_manager_consul |
+--------------------------+
checkmysql需要部署到每台
consul server中, 这样我们就实现了多点检测 MySQL 是否正常, 如果正常,
checkmysql会设置一个值为 1 的键:
mysql/mysqlxxxx/node-consul, 反之则值为 0, 其中
node-consul的默认值为当前主机的 hostname.
checkmysql检测完后, 我们使用 consul-template 工具根据模板文件
mysqlxxx.tpl来监听所有 key 的变更, 如果有变化则生成配置
mysqlxxxx.conf, 进而调用
masterha_manager_consul脚本开始进行切换.
我们在
masterha_manager_consul脚本中重写了方法
MHA::HealthCheck::wait_until_unreachable, 避免了无限循环检测, 如果少于一半的检测点认为数据库异常, 则退出该轮的调用, 否则启用子进程开始执行切换操作.
备注:
masterha_manager_consul是基于 MHA v0.5.6 修改的, 并且默认只在当天的21点到第二天的 9 点之间做自动切换, 可以通过
night选项控制此功能. 另外多台
consul server建议部署到不同的交换机或机柜中.
使用说明
代码见 mha_manager_consul 整体结构如下:
mha_manager_consul
├── bin
│ ├── checkmysql
│ └── masterha_manager_consul
├── conf
│ ├── db.cnf
│ └── template-config
├── consul
│ ├── acl
│ │ ├── policy.ano
│ │ └── policy.key
│ ├── conf
│ │ └── consul.conf
│ └── conf.d
│ └── server.json
├── README.md
└── template
└── mysql3308.tpl
测试环境
继续使用以往的测试环境:
| ip | os | hostname | version |
|---|---|---|---|
| 10.0.21.5 | centos 6.5 | cz-test1 | consul 0.8v |
| 10.0.21.7 | centos 6.5 | cz-test2 | consul 0.8v |
| 10.0.21.17 | centos 6.5 | cz-test3 | consul 0.8v |
下面所有的操作都假设已经安装好了
consul cluster.
备注
在运行
checkmysql之前, 我们需要设置好 acl 策略, 以免 consul 的敏感信息被旁人访问. 下面命令中的
token参数即是
consul主配置文件中的
acl_master_token选项, 文件
policy.ano则是限制匿名用户访问
mysql/*相关键的策略,
policy.key则是设置允许访问
mysql.*相关键的权限, 这里生成的 token 则为
dcb5b583-cd36-d39d-2b31-558bebf86502, 大家可以访问 consul acl 了解更多访问控制的内容.
#curl -X PUT --data @policy.ano http://localhost:8500/v1/acl/update?token=e95597e0-4045-11e7-a9ef-b6ba84687927
{"ID":"anonymous"}
#curl -X PUT --data @policy.key http://localhost:8500/v1/acl/update?token=e95597e0-4045-11e7-a9ef-b6ba84687927
{"ID":"dcb5b583-cd36-d39d-2b31-558bebf86502"}
checkmysql
在每个
consul server的节点上运行该脚本, 这里的
token参数即为上述 acl 的结果,
tag则是
db.conf配置里的实例, 通过以下命令启动:
perl checkmysql --conf db.cnf --verbose --tag mysql3308 --token dcb5b583-cd36-d39d-2b31-558bebf86502 [2017-06-08T10:09:14] mysql/mysql3308/cz-test2 with value 1 no change [2017-06-08T10:09:15] mysql/mysql3308/cz-test2 with value 1 no change
cz-test2表示当前的主机名是
cz-test2, 对应上述介绍的
node-consul.
备注
如果你的
MySQL master是通过 vip 提供服务,
db.conf配置里的 host 选项最好设置成 vip 的地址.
consul-template
在 checkmysql 更新 consul 的相关 key 之后, 如果有任意一个 checkmysql 变更了key 值, 则 consul-template 根据模板文件重新生成 mysqlxxx.conf 文件, 随后开始调用 masterha_manager_consul 脚本, consul-template 的配置详见
template-config; 通过以下命令启动:
# consul-template -config config 2017/05/25 10:11:13 [DEBUG] (logging) enabling syslog on LOCAL5
mysqlxxxx.tpl模板文件的内容如下:
# node3308 cz-test1:1 cz-test2:1 cz-test3:1
如果少于半数的监测点发现 MySQL 异常,
consul-template打印下面的消息:
[2017-06-08T10:24:15] status ok, skip switch..
反之则打印 error 信息, 并开始调用
masterha_manager_consul脚本:
[2017-05-25T10:24:48] status error, need switch.. Wed May 24 10:24:48 2017 - [info] Reading default configuration from /etc/masterha/app_default.cnf.. ... ...
conf.d/server.json
详见 template-config 配置中的 address = "consul.service.consul:8500" 选项; 在网络波动的情况下, address 选项如果只配置一个 consul server 的 ip 的话, consul-template 则不能连接到 consul server 中监控相应的 key 值, 尽管 consul-template 有重试功能, 但是在单 ip 的情况下, 难以确保可以正常获取相关的 key 值信息. conf.d/server.json 配置则将各个 consul server 的 ip 作为一个 dns 条目, 如下所示:
# dig @10.0.21.5 consul.service.consul ...... ...... ;; QUESTION SECTION: ;consul.service.consul. IN A ;; ANSWER SECTION: consul.service.consul. 0 IN A 10.0.21.7 consul.service.consul. 0 IN A 10.0.21.5 consul.service.consul. 0 IN A 10.0.21.17
单个 consul server 异常, 会自动跳到正常的 consul-server 中.
主从切换测试
我们简单关闭 master 的实例, 看看各工具间的输出状态.
关闭 master
关闭 master 后,
checkmysql脚本开始更新状态, 在超过半数的情况下调用
masterha_manager_consul脚本进行主从切换:
checkmysql脚本输出, 开始将 key 的值更为 0
[2017-06-08T18:16:43] mysql/mysql3308/cz-test2 with value 1 no change
DBI connect('mysql_read_default_file=./db.cnf;mysql_read_default_group=mysql3308','',...) failed: Can't connect to MySQL server on '10.0.21.7' (111) at checkmysql line 56
[2017-06-08T18:16:44] set 0 with key mysql/mysql3308/cz-test2 ok
DBI connect('mysql_read_default_file=./db.cnf;mysql_read_default_group=mysql3308','',...) failed: Can't connect to MySQL server on '10.0.21.7' (111) at checkmysql line 56
[2017-06-08T18:16:45] mysql/mysql3308/cz-test2 with value 0 no change
mysql3308.conf配置文件变更为如下:
# node3308 cz-test1:0 cz-test2:0 cz-test3:0
consul-template则显示如下:
# consul-template -config config 2017/06/08 12:11:13 [DEBUG] (logging) enabling syslog on LOCAL5 [2017-05-24T12:16:48] status error, need switch.. # 脚本判定超过半数认为数据库不可访问 Wed Jun 08 12:16:48 2017 - [info] Reading default configuration from /etc/masterha/app_default.cnf.. Wed Jun 08 12:16:48 2017 - [info] Reading application default configuration from /etc/masterha/app_56.conf.. Wed Jun 08 12:16:48 2017 - [info] Updating application default configuration from /usr/bin/init_conf_loads.. ....
如果没有超过半数, consul-template 则显示以下:
[2017-06-08T12:24:15] status ok, skip switch..
MHA 切换日志
mha 切换的日志则包含以下信息, 日志文件则根据 mha 的具体配置而定:
Wed Jun 08 12:45:37 2017 - [info] Starting master failover.. Wed Jun 08 12:45:37 2017 - [info] From: 10.0.21.7(10.0.21.7:3308) (current master) +--10.0.21.17(10.0.21.17:3308) To: 10.0.21.17(10.0.21.17:3308) (new master) ... ... Master failover to 10.0.21.17(10.0.21.17:3308) completed successfully. Wed Jun 08 12:45:41 2017 - [info] Sending mail..
总结
整体上而言, 使用
consul的架构相对繁琐, 没有单节点那么简易方便, 不过对于比较核心的数据库来说, 一致性应该放到首位, 多点检测则很大程度上健壮了切换机制. 而且原工具自带的
masterha_manager脚本本身只是循环检测, 超过三次错误(每次间隔时间递增)才会开始切换, 在网络波动, 交换机故障或数据库主机较繁忙的时候, 会引起一些意料之外的操作, 所以相对来说, 多点检测避免了这类不稳定的问题, 另外
consul cluster部署完成后也可以用于其他需要一致性判断的业务, 不用太纠结于繁琐方面的考虑.
编辑推荐:
- consul架构的 MHA 自动切换实例详解02-28
- Mybatis中#{}和${}有什么区别02-28
- 数据库表设计-邻接表、路径枚举、嵌套集、闭包表02-28
- 关于Mysql数据库的知识总结02-28
- pt-table-checksum校验与pt-table-sync修复数据02-28
- 分享csv导入数据到mysql实例02-28
- MySQL中key与index详细介绍02-28
- 云服务器Centos7.3安装mysql5.7.18 rpm安装步骤02-28
相关推荐
-
雷神推出 MIX PRO II 迷你主机:基于 Ultra 200H,玻璃上盖 + ARGB 灯效
2 月 9 日消息,雷神 (THUNDEROBOT) 现已宣布推出基于英
-
制造商 Musnap 推出彩色墨水屏电纸书 Ocean C:支持手写笔、第三方安卓应用
2 月 10 日消息,制造商 Musnap 现已在海外推出一款 Oce
热文推荐
- 数据库表设计-邻接表、路径枚举、嵌套集、闭包表
数据库表设计-邻接表、路径枚举、嵌套集、闭包表
26-02-28 - 内连接、左外连接、右外连接、交叉连接它们的区别是什么
内连接、左外连接、右外连接、交叉连接它们的区别是什么
26-02-28 - MySQL中关于四种事务隔离级别的详细介绍(图文)
MySQL中关于四种事务隔离级别的详细介绍(图文)
26-02-28 - myloader原理的实例讲解
myloader原理的实例讲解
26-02-28 - 教你解决怎么无法远程访问Mysql
教你解决怎么无法远程访问Mysql
26-02-28 - 详解介绍mydumper原理
详解介绍mydumper原理
26-02-28 - tpcc-mysql安装测试与使用的实例教程
tpcc-mysql安装测试与使用的实例教程
26-02-28 - MySQL— pymysql and SQLAlchemy
MySQL— pymysql and SQLAlchemy
26-02-28 - 什么是索引?Mysql目前主要的几种索引类型
什么是索引?Mysql目前主要的几种索引类型
26-02-28 - mysql5.7.18在window配置下免安装版的方法介绍(图文)
mysql5.7.18在window配置下免安装版的方法介绍(图文)
26-02-28
