MySQL高可用方案MGR+consul组合测试

这是学习笔记的第 1770篇文章

今天来简单理一下MGR和consul的组合方案,前期的准备和步骤还是比较多的,晚上完成了基础的调试,来来回回切换了好多次,还算有点意思。

首先要部署的就是consul服务,consul服务其实可以分为 consul server和consul agent, consul server的部署是分布式架构,所以最少需要3台服务器,而对于consul agent基于agent模式,部署起来也很便捷。

所以如果要完整的模拟一套consul+MGR的完整环境,我们可能需要配置如下的服务器:

6台服务器,其中3台作为consul server,另外3台作为MySQL服务器,单主模式,三个数据库实例节点的方式。其中consul server的3台服务器不是MGR集群独有,可以对接更多的业务,所以属于全局的需求,不是为了MGR特意定制。

第一阶段 consul服务部署

使用consul的方式查看集群的信息如下,可以看到是3个consul server,3台作为MGR节点。

[root@MySQL6 data]# consul members

Node Address Status Type Build Protocol DC Segment

tkconsulserver1 192.168.56.3:8301 alive server 1.2.1 2 company-b1 <all>

tkconsulserver2 192.168.56.4:8301 alive server 1.2.1 2 company-b1 <all>

tkconsulserver3 192.168.56.5:8301 alive server 1.2.1 2 company-b1 <all>

tkconsulclient4 192.168.56.6:8301 alive client 1.2.1 2 company-b1 <default>

tkconsulclient5 192.168.56.7:8301 alive client 1.2.1 2 company-b1 <default>

tkconsulclient6 192.168.56.8:8301 alive client 1.2.1 2 company-b1 <default>

consul server是这三台服务器:

192.168.56.3

192.168.56.4

192.168.56.5

主要的server的配置就需要一个server.json,这里有一个重要概念就是domain,这里是tk,也就是我们所属的一个域,通过域的方式来提供访问。

对于每台机器来说,advertise_addr是根据每台的实际IP来的,这里是192.168.56.3的服务器的配置,56.4,56.5的配置就可以按照类似的方式来做。

[root@MySQL3 consul]# cat server.json

{

"addresses": {

"http": "0.0.0.0",

"dns": "0.0.0.0"

},

"bind_addr": "0.0.0.0",

"advertise_addr": "192.168.56.3",

"bootstrap_expect": 3,

"datacenter": "company-b1",

"data_dir": "/data/consul",

"dns_config": {

"allow_stale": true,

"max_stale": "87600h",

"node_ttl": "0s",

"service_ttl": {

"*": "0s"

}

},

"domain": "tk",

"enable_syslog": false,

"leave_on_terminate": false,

"log_level": "info",

"node_name": "tkconsulserver1",

"node_meta": {

"location": "B1 in test"

},

"performance": {

"raft_multiplier": 1

},

"ports": {

"http": 8500,

"dns": 53

},

"reconnect_timeout": "72h",

"recursors": [

"192.168.56.4",

"192.168.56.5"

],

"retry_join": [

"192.168.56.4",

"192.168.56.5"

],

"retry_interval": "10s",

"server": true,

"skip_leave_on_interrupt": true,

"ui": true

}

对于客户端来说,需要的是一个client.json,这里就需要配置所有的consul server

[root@MySQL8 consul]# cat client.json

{

"addresses": {

"http": "0.0.0.0",

"dns": "0.0.0.0"

},

"bind_addr": "0.0.0.0",

"advertise_addr": "192.168.56.8",

"datacenter": "company-b1",

"data_dir": "/data/consul",

"enable_script_checks": true,

"enable_syslog": false,

"leave_on_terminate": true,

"log_level": "info",

"node_name": "tkconsulclient6",

"node_meta": {

"location": "B1 in test"

},

"ports": {

"dns": 8600,

"http": 8500

},

"rejoin_after_leave": true,

"retry_join": [

"192.168.56.3",

"192.168.56.4",

"192.168.56.5"

],

"retry_interval": "10s",

"skip_leave_on_interrupt": false

}

值得一提的是,客户端怎么去识别consul server发布的服务呢,这个是consul支持的域名服务来解决的,所以对于客户端来说,我们需要配置一下域名设置,把它们都指向consul server集群即可。

[root@MySQL6 data]# cat /etc/resolv.conf

; generated by /sbin/dhclient-script

nameserver 192.168.56.3

nameserver 192.168.56.4

nameserver 192.168.56.5

有了这种方式,我们就不用配置/etc/hosts来做本地域名解析了。

consul服务可以使用如下的命令来重启,或者可以使用supervisor来做。

/etc/init.d/consul_agent restart

第二阶段 MySQL集群MGR服务部署

部署MGR的部分完全可以做到自动化部署来快捷实现,如果本地要测试MGR,可以参考我之前写的一个开源脚本。

个人的小项目mysql_mgr_test开放了

我们来简单说明下手工在多台服务器上部署的细节。

我们预期的架构是三个节点,单主模式

192.168.56.7 Primary 端口:24801 内部端口:24901

192.168.56.6 Secondary 端口:24801 内部端口:24901

192.168.56.8 Secondary 端口:24801 内部端口:24901

MGR的版本相对来说是越新越好,我们选择的是MySQL 5.7.23

安装的数据目录在/data/mgr/s1下面。

使用如下的方式来初始化:

/usr/local/mysql_5.7.23/bin/mysqld --no-defaults --basedir=/usr/local/mysql_5.7.23 --datadir=/data/mgr/s1 --explicit_defaults_for_timestamp --initialize-insecure

然后配置参数文件,这是一个模板,里面需要注意的就是loose-group_replication_local_address是本地的IP,loose-group_replication_group_seeds是一个子集,不包含自己,为了方便测试,我们把参数文件放到数据目录下面。

参数文件内容如下:

[mysqld]

# server configuration

datadir=/data/mgr/s1

basedir=/usr/local/mysql_5.7.23

port=24801

socket=/data/mgr/s1/s1.sock

server_id=24803

gtid_mode=ON

enforce_gtid_consistency=ON

master_info_repository=TABLE

relay_log_info_repository=TABLE

binlog_checksum=NONE

log_slave_updates=ON

log_bin=binlog

binlog_format=ROW

transaction_write_set_extraction=XXHASH64

loose-group_replication_group_name="1bb1b861-f776-11e6-be42-782bcb377193"

loose-group_replication_start_on_boot=off

loose-group_replication_local_address= "192.168.56.8:24901"

loose-group_replication_group_seeds= "192.168.56.6:24901,192.168.56.7:24901"

loose-group_replication_bootstrap_group= off

我们需要配置数据目录的属主是mysql.mysql

chown -R mysql.mysql /data/mgr/s1

然后使用如下的方式来启动MySQL服务。

/usr/local/mysql_5.7.23/bin/mysqld_safe --defaults-file=/data/mgr/s1/s1.cnf &

节点1创建复制用户:

create user rpl_user@'%';

grant replication slave on *.* to rpl_user@'%' identified by 'rpl_pass';

三个节点都执行如下的步骤,安装复制插件,配置复制关系。

INSTALL PLUGIN group_replication SONAME 'group_replication.so';

show plugins;

change master to master_user='rpl_user',master_password='rpl_pass' for channel 'group_replication_recovery';

节点1开启group replication的步骤如下:

SET GLOBAL group_replication_bootstrap_group = ON;

START GROUP_REPLICATION;

SELECT * FROM performance_schema.replication_group_members;

节点2和节点3的操作如下:

set global group_replication_allow_local_disjoint_gtids_join=ON;

START GROUP_REPLICATION;

按照这种方式启动集群基本上还是比较顺畅的。

在这个基础上,我们队集群做一些验证测试。

第三阶段 MySQL集群MGR和consul结合

MGR集群在可用的前提下,接入consul实现平滑的切换是本次测试的重中之重。根据consul的机制,我们需要提供相应的健康检查脚本。

参考了网上的一些脚本,自己稍作改进:

Primary节点的健康检查脚本如下,角色完全可以基于MGR自己的数据字典来完成。

[root@MySQL6 data]# cat /data/consul/scripts/check_mgr_primary.sh

#!/bin/bash

port=$1

user="root"

comm="/usr/local/mysql_5.7.23/bin/mysql -u$user -h 127.0.0.1 -P $port "

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';"`

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

Secondary节点的健康检查脚本如下:

[root@MySQL6 data]# cat /data/consul/scripts/check_mgr_secondary.sh

#!/bin/bash

port=$1

user="root"

comm="/usr/local/mysql_5.7.23/bin/mysql -u$user -h 127.0.0.1 -P $port "

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

这里的重点是需要配置文件,我们可以归类为两类,一类是读请求,是只能对接到Primary节点,还有两个读节点,可以通过consul域名的方式实现负载均衡。所以我们根据这个需求可以定制两个json模板。

写节点的json配置

[root@MySQL8 consul]# cat

{

"services": [

{

"id": "mysql_mgr_w",

"name": "test24801-mysql_w",

"address": "",

"port": 24801,

"enable_tag_override": false,

"checks": [

{

"id": "mysql_mgr_w-check-01",

"name": "MySQL Write Check",

"args": ["/data/consul/scripts/check_mgr_primary.sh","24801"],

"interval": "15s",

"timeout": "1s",

"service_id": "mysql_mgr_w"

}

]

}

]

}

读节点的json配置:

[root@MySQL8 consul]# cat test_mgr_read.db.json

{

"services": [

{

"id": "mysql_mgr_r",

"name": "test24801-mysql_r",

"address": "",

"port": 24801,

"enable_tag_override": false,

"checks": [

{

"id": "mysql_mgr_r-check-02",

"name": "MySQL Write Check",

"args": ["/data/consul/scripts/check_mgr_secondary.sh","24801"],

"interval": "15s",

"timeout": "1s",

"service_id": "mysql_mgr_r"

}

]

}

]

}

使用如下的域名方式可以解析得到写节点的IP:

ping test24801-mysql_w.service.tk

PING test24801-mysql_w.service.tk (192.168.56.7) 56(84) bytes of data.

64 bytes from MySQL7 (192.168.56.7): icmp_seq=1 ttl=64 time=0.299 ms

64 bytes from MySQL7 (192.168.56.7): icmp_seq=2 ttl=64 time=0.340 ms

而对于读节点来说,可以通过负载均衡来对接两个读节点

我们可以使用这种方式来解析对应的DNS

[root@MySQL8 consul]# ping test24801-mysql_r.service.tk

PING test24801-mysql_r.service.tk (192.168.56.6) 56(84) bytes of data.

64 bytes from MySQL6 (192.168.56.6): icmp_seq=1 ttl=64 time=0.281 ms

^C

--- test24801-mysql_r.service.tk ping statistics ---

1 packets transmitted, 1 received, 0% packet loss, time 862ms

rtt min/avg/max/mdev = 0.281/0.281/0.281/0.000 ms

.....

[root@MySQL8 consul]# ping test24801-mysql_r.service.tk

PING test24801-mysql_r.service.tk (192.168.56.8) 56(84) bytes of data.

64 bytes from MySQL8 (192.168.56.8): icmp_seq=1 ttl=64 time=0.008 ms

64 bytes from MySQL8 (192.168.56.8): icmp_seq=2 ttl=64 time=0.029 ms

到了这个阶段开始,基本的任务就完成了。可以kill掉56.7节点上的MySQL实例进程,然后集群会依次切换,会有56.8的节点来接管,作为新的Primary。consul服务会在这个过程中完成服务的注销和自动发现,这也就是配置脚本test_mgr_read.db.json 和 test_mgr_write.db.json 来对接的。

后续根据大家的反馈来不断的细化和完善。

原文发布于微信公众号 - 杨建荣的学习笔记(jianrong-notes)

原文发表时间:2018-10-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏云计算教程系列

如何在CentOS上安装MySQL

MySQL是一种流行的数据库管理系统,用于Web和服务器应用程序。本教程将介绍如何在CentOS 6上安装,配置和管理MySQL。

26370
来自专栏云计算教程系列

如何使用MySQLTuner优化MySQL性能

MySQLTuner是一个用Perl编写的脚本,帮助你提高MySQL性能及稳定性。它通过检索当前配置变量和状态数据,提供一些基本性能建议。

20650
来自专栏腾讯云数据库(TencentDB)

MySQL 8.0 版本功能变更介绍

作者介绍:朱强,腾讯云数据库高级工程师,主要负责腾讯云数据库MySQL的开发和运营,曾就职于华为和网宿,在存储、文件系统开发有丰富经验。

1.4K560
来自专栏NetCore

【强烈推荐】数据库迁移利器:Migrator.Net

简介 很郁闷,写了一天的遇到LiveWriter错误,可恶啊 几年前在做项目中第一次接触到了Migrator.Net,就深深被吸引住了,至此以后在新的大项目中,...

23250
来自专栏数据和云

Oracle 12.2新特性掌上手册 - 第六卷 ADG的性能与诊断

编辑手记:在Oracle 12.2中,ADG有许多惊人的改进,通过ADG standby数据库的性能数据收集和诊断、快照standby数据库的应用,以及实时的数...

40170
来自专栏张秀云的专栏

MySQL 压缩解决方案(一)

本文描述 mysql 压缩的使用场景和解决方案,包括压缩传输协议、压缩列解决方案和压缩表解决方案。

3.3K10
来自专栏IT技术精选文摘

MySQL高可用方案

第一种:主从复制+读写分离 客户端通过Master对数据库进行写操作,slave端进行读操作,并可进行备份。Master出现问题后,可以手动将应用切换到slav...

46880
来自专栏java学习

SSM框架原理,作用及使用方法

注:本公众号纯属个人公益公众号!不存在任何收费项目!免费分享所有学习资料!只求大家多多支持!多多关注!!

8700
来自专栏云计算

如何在Debian 9上设置MariaDB

MariaDB是MySQL的直接替代品。它致力于成为寻求强大,可扩展且可靠的SQL Server的数据库专业人员的合理选择。本指南将帮助初学者在Debian 9...

1.2K30
来自专栏容器云生态

Docker监控方案(TIG)的研究与实践之Influxdb

前言: Influxdb也是有influxdata公司(www.influxdata.com )开发的用于数据存储的时间序列数据库.可用于数据的时间排列。在整个...

32880

扫码关注云+社区

领取腾讯云代金券