前面的文章有提到过利用consul+mha实现mysql的高可用,以及利用consul+sentinel实现redis的高可用,具体的请查看:http://www.cnblogs.com/gomysql/p/8010552.html。本次给你们带来mysql高可用的新玩法,利用mysql 5.7的mgr+consul实现,至于mgr是什么,有什么优点,如何搭建这里就不说了,你们本身google,我这里就是介绍利用mgr+consul实现高可用及故障自动切换。至于consul是什么能够参考前面的文章。html
环境:mgr至少须要3个节点。数据库版本:mysql 5.7.19node
我这里使用单主模式。mysql
192.168.100.78
192.168.100.75
192.168.100.74redis
mgr搭建完成之后查看状态:sql
[root@localhost][performance_schema]> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | group_replication_applier | 8e4d93b8-4dd1-11e8-8306-6c92bf7e18e2 | ym_DB_16_100075 | 3306 | ONLINE | | group_replication_applier | 9062a0ef-4dd1-11e8-8822-6c92bf744dd6 | ym_DB_15_100074 | 3306 | ONLINE | | group_replication_applier | 9a7e7cd5-4dd1-11e8-b28c-6c92bf7e0d2e | ym_DB_19_100078 | 3306 | ONLINE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+
查看主节点是哪一个(个人环境是单主,官方也是推荐使用单主)shell
[root@localhost][performance_schema]> select * from performance_schema.replication_group_members where member_id =(select variable_value from performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'); +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | group_replication_applier | 8e4d93b8-4dd1-11e8-8306-6c92bf7e18e2 | ym_DB_16_100075 | 3306 | ONLINE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ 1 row in set (0.00 sec)
能够看见我目前的主节点是100.75。到此mgr环境ok。下面到部署consul,前面的文章提到过,须要服务发现的机器都须要安装consul客户端,也就是3台服务器都须要安装。其中涉及到2个检查脚本(脚本不够完善,好比复制延时是否进行注册)。
主节点检查脚本:数据库
#!/bin/bash port=$1 user="root" passwod="123" comm="/usr/local/mysql/bin/mysql -u$user -h 127.0.0.1 -P $port -p$passwod" value=`$comm -Nse "select 1"` primary_member=`$comm -Nse "select variable_value from performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'"` server_uuid=`$comm -Nse "select variable_value from performance_schema.global_variables where VARIABLE_NAME='server_uuid';"` # 判断mysql是否存活 if [ -z $value ] then echo "mysql $port is down....." exit 2 fi # 判断节点状态 node_state=`$comm -Nse "select MEMBER_STATE from performance_schema.replication_group_members where MEMBER_ID='$server_uuid'"` if [ $node_state != "ONLINE" ] then echo "MySQL $port state is not online...." exit 2 fi # 判断是否是主节点 if [[ $server_uuid == $primary_member ]] then echo "MySQL $port Instance is master ........" exit 0 else echo "MySQL $port Instance is slave ........" exit 2 fi
从节点检查脚本:json
#!/bin/bash port=$1 user="root" passwod="123" comm="/usr/local/mysql/bin/mysql -u$user -h 127.0.0.1 -P $port -p$passwod" value=`$comm -Nse "select 1"` primary_member=`$comm -Nse "select variable_value from performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'"` server_uuid=`$comm -Nse "select variable_value from performance_schema.global_variables where VARIABLE_NAME='server_uuid';"` # 判断mysql是否存活 if [ -z $value ] then echo "mysql $port is down....." exit 2 fi # 判断节点状态 node_state=`$comm -Nse "select MEMBER_STATE from performance_schema.replication_group_members where MEMBER_ID='$server_uuid'"` if [ $node_state != "ONLINE" ] then echo "MySQL $port state is not online...." exit 2 fi # 判断是否是主节点 if [[ $server_uuid != $primary_member ]] then echo "MySQL $port Instance is slave ........" exit 0 else node_num=`$comm -Nse "select count(*) from performance_schema.replication_group_members"` # 判断若是没有任何从节点,主节点也注册从角色服务。 if [ $node_num -eq 1 ] then echo "MySQL $port Instance is slave ........" exit 0 else echo "MySQL $port Instance is master ........" exit 2 fi fi
其中一台服务器的consul配置文件,有master和slave,以下:bash
[root@ym_DB_16_100075 conf]# cat payment-3306-mydb-ser.json { "services": [ { "name": "payment-3306-mydb-ser", "tags": [ "充值-3306" ], "address": "192.168.100.75", "port": 3306, "checks": [ { "script": "/usr/local/consul/shell/check_mysql_mgr_master.sh 3306", "interval": "15s" } ] } ] }
[root@ym_DB_16_100075 conf]# cat r-payment-3306-mydb-ser.json { "services": [ { "name": "r-payment-3306-mydb-ser", "tags": [ "充值-3306" ], "address": "192.168.100.75", "port": 3306, "checks": [ { "script": "/usr/local/consul/shell/check_mysql_mgr_slave.sh 3306", "interval": "15s" } ] } ] }
其余两台服务器配置文件同样,只是"address"改为对应服务器的地址就完事。启动consul。ping其中一个域名,好比:payment-3306-mydb-ser.service.consul,那么返回的是主节点的ip,由于这个域名是写的。若是ping r-payment-3306-mydb-ser.service.consul,那么返回的是另外两个从节点的ip。服务器
从上面能够看到写的域名解析到的主节点,读的域名解析到了2个从节点,从节点能够实现负载均衡的效果。
故障测试:
1. 把主节点停掉,查看写的域名payment-3306-mydb-ser.service.consul会解析到哪里。
[root@localhost][(none)]> select * from performance_schema.replication_group_members; +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | group_replication_applier | 9062a0ef-4dd1-11e8-8822-6c92bf744dd6 | ym_DB_15_100074 | 3306 | ONLINE | | group_replication_applier | 9a7e7cd5-4dd1-11e8-b28c-6c92bf7e0d2e | ym_DB_19_100078 | 3306 | ONLINE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ 2 rows in set (0.00 sec)
停掉之后发现以前的100.75主节点已经被移除,已经自动选出新的节点:
[root@localhost][(none)]> select * from performance_schema.replication_group_members where member_id =(select variable_value from performance_schema.global_status WHERE VARIABLE_NAME= 'group_replication_primary_member'); +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | CHANNEL_NAME | MEMBER_ID | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+ | group_replication_applier | 9062a0ef-4dd1-11e8-8822-6c92bf744dd6 | ym_DB_15_100074 | 3306 | ONLINE | +---------------------------+--------------------------------------+-----------------+-------------+--------------+
能够看到如今的主节点已是100.74,那么咱们看看域名payment-3306-mydb-ser.service.consul解析到哪里:
能够看到没有问题,正常。再看看读域名:r-payment-3306-mydb-ser.service.consul
能够看到一切正常。后续检查脚本能够判断是否延时,若是延时就不注册服务。