MHA高可用集群架构
Posted ღ᭄小艾ヅ࿐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MHA高可用集群架构相关的知识,希望对你有一定的参考价值。
一、MHA
1.什么是MHA:
2.MHA工作原理:
- 当master出现故障时,通过对比slave之间io线程读取master上binlog的位置,选取最接近的slave作为最新的slave(laster slave)
- 其他slave通过与laster slave对比生成差异中继日志,并应用
- 在laster slave上应用从master保存的binlog,同时将laster slave提升为master
- 最后在其他slave上应用相应的差异中继日志并开始从新的master开始复制
3.MHA组件:
- MHA Manager(管理节点):
MHA Manager可以单独部署在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上- MHA Node(数据节点):
MHA Node运行在每台mysql服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明
4.MHA组件介绍:
- MHA Manager:
运行一些工具,比如masterha_manager工具实现自动监控MySQL Master和实现master故障切换,其他工具手动实现master故障切换,在线master转移,连接检查等等。一个Manager可以管理多个master-slave集群- MHA Node:
部署在所有运行MySQL的服务器上,无论是master还是slave。主要有三个作用
- 保存二进制日志
如果能够访问故障master,会拷贝master的二进制日志- 应用差异中继日志
从拥有最新数据的slave上生成差异中继日志,然后应用差异日志- 清除中继日志
在不停止SQL线程的情况下删除中继日志
5.MHA工具介绍:
1).Manager工具:
2).Node工具:
- Node这些工具通常由MHA Manager的脚本触发,无需人工操作
二、MHA部署架构
1.部署规划:
角色 | ip | 主机名 | server-id | 功能 | 备注 |
---|---|---|---|---|---|
MHA-Manager | 192.168.74.26 | mha-manager | - | 管理节点 | |
MHA-Node(Master) | 192.168.74.27 | master | 10 | 数据节点 | 写 |
MHA-Node(Slave1) | 192.168.74.28 | slave1 | 20 | 数据节点 | 读 |
MHA-Node(Slave2) | 192.168.74.29 | slave2 | 30 | 数据节点 | 读 |
- 绑定主机ip和主机名称到/etc/hosts中(四台都需要)
- 配置epel源:(四台都要)
进入腾讯镜像站
- 配置本地自建仓库的yum源(四台都要)
mkdir -p /soft/mha
将这个文件上传此目录下,我把需要用到的都下载到这个文件里了
- vi /etc/yum.repos.d/local.repo
- 测试MHA依赖软件库的安装:
yum -y install perl-DBD-MySQL
perl-Config-Tiny
perl-Time-HiRes
perl-Mail-Sender
perl-Mail-Sendmail
perl-MIME-Base32
perl-MIME-Charset
perl-MIME-EncWords
perl-Params-Classify
perl-Params-Validate.x86_64
perl-Log-Dispatch
perl-Parallel-ForkManager
net-tools
2.部署MySQL主从复制环境:
- 数据库安装位置:/usr/local/mysql
- 数据库的数据目录:/usr/local/mysql/data
- 套接字文件:/tmp/mysql.sock
- 端口:3306
- 配置文件位置:/usr/local/mysql/my.cnf
1).master主服务器:
- 第一步:上传mysql软件包
- 第二步:使用脚本安装MySQL软件
vi mysql.sh
#!/bin/bash
yum install -y libaio
tar -zxf mysql-5.7.34-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.34-linux-glibc2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir mysql-files
chown mysql:mysql mysql-files
chmod 750 mysql-files
bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql &> /root/password.txt
bin/mysql_ssl_rsa_setup --datadir=/usr/local/mysql/data
cp support-files/mysql.server /etc/init.d/mysql
service mysql start
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile
然后source这个脚本即可
- 第三步:设置密码(set password=’******’)
- 第四步:进行安全初始化
mysql_secure_installation- 第五步:编写master主机中my.cnf配置文件
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/master.err
log-bin=/usr/local/mysql/data/binlog
server-id=10
character_set_server=utf8mb4
gtid-mode=on
log-slave-updates=1
enforce-gtid-consistency
重启mysql
2).slave1,slave2从服务器:
- 前面步骤同,但是不用进行初始化,通过脚本实现:
#!/bin/bash
yum install -y libaio
mv mysql-5.7.34-linux-glibc2.12-x86_64 /usr/local/mysql
useradd -r -s /sbin/nologin mysql
rm -rf /etc/my.cnf
cd /usr/local/mysql
mkdir mysql-files
chown mysql:mysql mysql-files
chmod 750 mysql-files
cp support-files/mysql.server /etc/init.d/mysql
echo 'export PATH=$PATH:/usr/local/mysql/bin' >> /etc/profile
source /etc/profile
- 第二步:使用rsync把master服务器中的data数据目录同步到slave1和slave2从服务器中
现在master中删除rm -rf /usr/local/mysql/data/auto.cnf
rsync -av /usr/local/mysql/data root@192.168.74.28:/usr/local/mysql/
rsync -av /usr/local/mysql/data root@192.168.74.29:/usr/local/mysql/- 第三步:给slave1和slave2配置my.cnf文件
slave1:
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/slave1.err
relay-log=/usr/local/mysql/data/relaylog
log-bin=/usr/local/mysql/data/binlog
server-id=20
character_set_server=utf8mb4
log-slave-updates=1
gtid-mode=on
enforce-gtid-consistency
skip-slave-start
slave2:
[mysqld]
basedir=/usr/local/mysql
datadir=/usr/local/mysql/data
socket=/tmp/mysql.sock
port=3306
log-error=/usr/local/mysql/data/slave2.err
relay-log=/usr/local/mysql/data/relaylog
log-bin=/usr/local/mysql/data/binlog
server-id=30
character_set_server=utf8mb4
log-slave-updates=1
gtid-mode=on
enforce-gtid-consistency
skip-slave-start
- 第四步:配置完成后,启动mysql
3.配置主从数据同步:
- 第一步:在master服务器中创建一个slave同步账号
- 第二步:创建一个mha账号(方便后期MHA监控主从同步的状态)
- 第三步:在slave1和slave2中配置主从数据同步(两台slave都配置)
弄好之后,show slave status\\G查看一下,确保Slave_IO_Running和Slave_SQL_Running都为yes
4.MHA软件的安装:
- 说明:在所有节点安装mha-node软件包,在mha管理端安装mha-manager软件包
- 上传软件包到相应的主机,然后使用yum install下载
1).配置ssh互信(免密登入):
- 说明:
- 在生产环境中几乎都是禁止root远程登入服务器的,所以ssh免密登入要在admin用户下进行配置,这是出于安全角度考虑出发
- admin用户可以是任意普通用户
- 该普通用户用于mha的管理节点远程访问mysql复制组中的所有主机,完成一些其他工作
- 第一步:在所有机器上创建一个普通账号admin
- 第二步:配置mha主机到其他主机的admin用户互信
在mha这台主机上切换到admin用户下
使用for循环拷贝公钥到其他三台主机上
然后用ssh连接测试一下- ssh免密只需要拷贝公钥,但是以上代码把整个.ssh目录拷贝过去了。
答:因为MHA的互信,要求不仅仅是MHA免密到master,slave1,slave2,master也要免密到MHA,slave1,slave2…
2).配置admin用户的sudo权限:
master,slave1,slave2三台主机都要(当发生故障时,从服务器也可以自己设置ip):
#User_Alias 表示具有sudo权限的用 户 列表; Host_Alias表示主机的列表
User_Alias MYSQL_USERS = admin
#Runas_Alias 表示用户以什么身份登录
Runas_Alias MYSQL_RUNAS = root
#Cmnd_Alias 表示允许执行命令的列表(命令需使用完整路径)
Cmnd_Alias MYSQL_CMNDS = /sbin/ifconfig,/sbin/arping
MYSQL_USERS ALL = (MYSQL_RUNAS) NOPASSWD: MYSQL_CMNDS
- 第二步:测试admin用户是否可以挂载vip(只能在master机器上挂载vip)
先切换到admin用户下
3).创建mha相关配置文件:
- 第一步:在mha服务器上创建工作目录
- 第二步:创建mha局部配置文件
vi /etc/mha/app1.cnf
[server default]
# 设置监控用户和密码
user=mha
password=123456
# 设置复制环境中的复制用户和密码
repl_user=slave
repl_password=123456
# 设置ssh的登录用户名
ssh_user=admin
# 设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
ping_interval=3
# 设置mgr的工作目录
manager_workdir=/data/mha/masterha/app1
# 设置mysql master保存binlog的目录,以便MHA可以找到master的二进制日志
master_binlog_dir=/usr/local/mysql/data
# 设置master的pid文件
master_pid_file=/usr/local/mysql/data/master.pid
# 设置mysql master在发生切换时保存binlog的目录(在mysql master上创建这个目录)
remote_workdir=/data/mysql/mha
# 设置mgr日志文件(MHA出现问题,主要看这个日志)
manager_log=/data/mha/masterha/app1/app1-3306.log
# MHA到master的监控之间出现问题,MHA Manager将会尝试从slave1和slave2登录到master上
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.74.28 -s 192.168.74.29 --user=admin --port=22 --master_host=192.168.74.27 --master_port=3306
# 设置自动failover时候的切换脚本
master_ip_failover_script="/etc/mha/master_ip_failover.sh 192.168.74.100 1"
# 设置手动切换时候的切换脚本(故障发生时,自动挂载vip到slave1或者slave2)
#master_ip_online_change_script="/etc/mha/master_ip_online_change.sh 192.168.74.100 1"
# 设置故障发生后关闭故障主机脚本
# shutdown_script="/etc/mha/power_manager"
[server1]
hostname=192.168.74.27
port= 3306
candidate_master=1
[server2]
hostname=192.168.74.28
port= 3306
candidate_master=1
[server3]
hostname=192.168.74.29
port= 3307=6
candidate_master=1
4).上传相应脚本/etc/mha目录:
master_ip_failover.sh
脚本内容如下:
#!/usr/bin/env perl
# Copyright (C) 2011 DeNA Co.,Ltd.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
## Note: This is a sample script and is not complete. Modify the script based on your environment.
#!/usr/bin/env perl
#!/usr/bin/env perl
use strict;
use warnings FATAL => 'all';
use Getopt::Long;
my (
$command, $ssh_user, $orig_master_host, $orig_master_ip,
$orig_master_port, $new_master_host, $new_master_ip, $new_master_port
);
#my $gateway = '10.77.133.1';
my $vip = shift;
#my $bcast = '10.77.133.255';
#my $netmask = '255.255.255.0';
my $interface = 'ens33';
my $key = shift;
#my $ssh_start_vip = "sudo /sbin/ifconfig $interface:$key $vip netmask $netmask && sudo /sbin/arping -f -q -c 5 -w 5 -I $interface -s $vip -U $gateway";
my $ssh_stop_vip = "sudo /sbin/ifconfig $interface:$key down";
GetOptions(
'command=s' => \\$command,
'ssh_user=s' => \\$ssh_user,
'orig_master_host=s' => \\$orig_master_host,
'orig_master_ip=s' => \\$orig_master_ip,
'orig_master_port=i' => \\$orig_master_port,
'new_master_host=s' => \\$new_master_host,
'new_master_ip=s' => \\$new_master_ip,
'new_master_port=i' => \\$new_master_port,
);
exit &main();
sub main {
#print "\\n\\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\\n\\n";
if ( $command eq "stop" || $command eq "stopssh" ) {
my $exit_code = 1;
eval {
print "Disabling the VIP on old master: $orig_master_host \\n";
&stop_vip();
$exit_code = 0;
};
if ($@) {
warn "Got Error: $@\\n";
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "start" ) {
my $exit_code = 10;
eval {
print "Enabling the VIP - $vip on the new master - $new_master_host \\n";
&start_vip();
$exit_code = 0;
};
if ($@) {
warn $@;
exit $exit_code;
}
exit $exit_code;
}
elsif ( $command eq "status" ) {
print "Checking the Status of the script.. OK \\n";
exit 0;
}
else {
&usage();
exit 1;
}
}
sub start_vip() {
my $bcast = `ssh $ssh_user\\@$new_master_host sudo /sbin/ifconfig | grep 'Bcast' | head -1 | awk '{print \\$3}' | awk -F":" '{print \\$2}'`;
chomp $bcast;
my $gateway = `ssh $ssh_user\\@$new_master_host sudo /sbin/route -n | grep 'UG' | awk '{print \\$2}'`;
chomp $gateway;
my $netmask = `ssh $ssh_user\\@$new_master_host sudo /sbin/ifconfig | grep 'Bcast' | head -1 | awk '{print \\$4}' | awk -F":" '{print \\$2}'`;
chomp $netmask;
my $ssh_start_vip = "sudo /sbin/ifconfig $interface:$key $vip broadcast $bcast netmask $netmask && sudo /sbin/arping -f -q -c 5 -w 5 -I $interface -s $vip -U $gateway";
print "=======$ssh_start_vip=================\\n";
`ssh $ssh_user\\@$new_master_host \\" $ssh_start_vip \\"`;
}
sub stop_vip() {
my $ssh_user = "admin";
print "=======$ssh_stop_vip==================\\n";
`ssh $ssh_user\\@$orig_master_host \\" $ssh_stop_vip \\"`;
}
sub usage {
print
"Usage: master_ip_failover --command=start|stop|stopssh|status --orig_master_host=host --orig_master_ip=ip --orig_master_port=port --new_master_host=host --new_master_ip=ip --new_master_port=port\\n";
}
5).检测ssh互信以及MySQL主从状态:
在mha服务器上切换到admin用户在
- 检查ssh互信
- 检查集群状态
6).检查MHA状态,然后运行MHA(监控开始):
MHA:
5.自动Failover测试:
- 第一步:在master服务器上安装测试工具
yum install -y sysbench- 第二步:插入测试数据
[root@master ~]# sysbench /usr/share/sysbench/oltp_read_only.lua \\
--mysql-host=192.168.74.27 --mysql-port=3306 --mysql-user=mha \\
--mysql-password=123456 --mysql-socket=/tmp/mysql.sock \\
--mysql-db=test --db-driver=mysql --tables=1 \\
--table-size=100000 --report-interval=10 --threads=128 --time=120 prepare
mysql> select count(*) from sbtest1;
+----------+
| count(*) |
+----------+
| 100000 |
+----------+
1 row in set (0.01 sec)
- 第三步:模拟master服务器故障
以上是关于MHA高可用集群架构的主要内容,如果未能解决你的问题,请参考以下文章