前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MySQL高可用方案MGR+consul组合测试

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

作者头像
jeanron100
发布2018-10-24 11:15:05
2.1K0
发布2018-10-24 11:15:05
举报

这是学习笔记的第 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 来对接的。

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

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 杨建荣的学习笔记 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 MySQL
腾讯云数据库 MySQL(TencentDB for MySQL)为用户提供安全可靠,性能卓越、易于维护的企业级云数据库服务。其具备6大企业级特性,包括企业级定制内核、企业级高可用、企业级高可靠、企业级安全、企业级扩展以及企业级智能运维。通过使用腾讯云数据库 MySQL,可实现分钟级别的数据库部署、弹性扩展以及全自动化的运维管理,不仅经济实惠,而且稳定可靠,易于运维。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档