千家信息网

什么是MHA高可用集群架构

发表于:2024-11-28 作者:千家信息网编辑
千家信息网最后更新 2024年11月28日,MHA 简介简介MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的 youshimaton(现就职于 Face
千家信息网最后更新 2024年11月28日什么是MHA高可用集群架构

MHA 简介

简介

MHA(Master High Availability)目前在 MySQL 高可用方面是一个相对成熟的解决方案,它由日本 DeNA 公司的 youshimaton(现就职于 Facebook 公司)开发,是一套优秀的作为 MySQL 高可用性环境下故障切换和主从提升的高可用软件。

在 MySQL 故障切换过程中,MHA 能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程中,MHA 能在最大程度上保证数据的一致性,以达到真正意义上的高可用。

该软件由两部分组成

MHA Manager(管理节点)和MHA Node(数据节点)。MHA Manager可以单独部署在一个独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

工作过程

从宕机崩溃的master保存二进制日志文件事件

识别含有最新更新的slave

应用差异的中继日志(relay-log)到其他的slave

应用从master保存的二进制日志事件

提升一个slave为新的master

使其他的slave连接新的master进行复制

实验环境

master(192.168.149.29)

slave1(192.168.149.130)

slave2(192.168.149.128)

manager(192.168.149.150)

实验步骤

在三台主从服务器上安装mysql数据库

#安装编译依赖环境
[root@master ~] yum -y install gcc gcc-c++ ncurses ncurses-devel bison perl-Module-Install cmake
[root@master ~]# mount.cifs //192.168.100.100/tools /mnt/tools/ ##挂载工具包
Password for root@//192.168.100.100/tools:
[root@master ~]# cd /mnt/tools/MHA/
[root@master MHA]# tar xf cmake-2.8.6.tar.gz -C /opt/ ##解压
[root@master mnt] cd /opt/cmake-2.8.6/
[root@master MHA]# cd /opt/cmake-2.8.6/ ##配置
[root@master cmake-2.8.6] gmake && gmake install ##编译安装
#安装mysql数据库
[root@master cmake-2.8.6]# cd /mnt/tools/MHA/
[root@master MHA]# tar xf mysql-5.6.36.tar.gz -C /opt/t ##解压MySQL
#编译mysql
[root@master MHA]# cd /opt/mysql-5.6.36/
[root@master mysql-5.6.36]# cmake -DCMAKE_INSTALL_PREFIX=/usr/local/mysql \
-DDEFAULT_CHARSET=utf8 \ ##指定字符集
-DDEFAULT_COLLATION=utf8_general_ci \ ##指定字符集默认
-DWITH_EXTRA_CHARSETS=all \ ##关联额外的所有字符集
-DSYSCONFDIR=/etc ##配置文件目录
#安装
[root@master mysql-5.6.36]# make && make install ##编译安装
#设置环境变量
[root@master mysql-5.6.36]# cp support-files/my-default.cnf /etc/my.cnf ##复制配置文件
[root@master mysql-5.6.36]# cp support-files/mysql.server /etc/rc.d/init.d/mysqld
##复制启动脚本
[root@master mysql-5.6.36]# chmod +x /etc/rc.d/init.d/mysqld ##给执行权限
[root@master mysql-5.6.36]# chkconfig --add mysqld ##添加到service管理中
[root@master mysql-5.6.36]# echo "PATH=$PATH:/usr/local/mysql/bin" >> /etc/profile
##修改环境变量
[root@master mysql-5.6.36]# source /etc/profile ##刷新华宁变量
#创建mysql数据库,并授权
[root@master mysql-5.6.36]# groupadd mysql ##创建组
[root@master mysql-5.6.36]# useradd -M -s /sbin/nologin mysql -g mysql
##创建系统用户
[root@master mysql-5.6.36]# chown -R mysql.mysql /usr/local/mysql ##修改属组属主
[root@master mysql-5.6.36]# mkdir -p /data/mysql ##创建数据目录
#初始化数据库
[root@master mysql-5.6.36]# /usr/local/mysql/scripts/mysql_install_db \
--basedir=/usr/local/mysql \ ##文件目录
--datadir=/usr/local/mysql/data \ ##数据目录
--user=mysql ##用户

修改 mysql 的主配置文件:/etc/my.cnf

##配置主服务器:
[root@master mysql-5.6.36]# vim /etc/my.cnf
[mysql]
server-id = 1
#开启二进制日志
log_bin = master-bin
#允许从服务器进行同步
log-slave-updates = true

##配置从服务器1:
[root@slave1 mysql-5.6.36]# vim /etc/my.cnf
[mysql]
server-id = 2
#开启二进制日志
log_bin = master-bin
#使用中继日志进行同步
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index

##配置从服务器2:
[root@slave2 mysql-5.6.36]# vim /etc/my.cnf
[mysql]
server-id = 3
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index

三台服务器启动 mysql 服务

#在三台服务器上分别创建这两个个软链接
[root@master mysql-5.6.36]# ln -s /usr/local/mysql/bin/mysql /usr/sbin/
[root@master mysql-5.6.36]# ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

#启动mysql
[root@master mysql-5.6.36]# /usr/local/mysql/bin/mysqld_safe --user=mysql &
#关闭防火墙和安全功能
[root@master mysql-5.6.36]# systemctl stop firewalld.service
[root@master mysql-5.6.36]# setenforce 0

配置 Mysql 主从同步(一主两从)在所有数据库节点上授权两个用户

[root@master mysql-5.6.36]# mysql -u root -p //进入数据库
mysql> grant replication slave on . to 'myslave'@'192.168.52.%' identified by '123';
##从数据库同步使用用户myslave
mysql> grant all privileges on . to 'mha'@'192.168.52.%' identified by 'manager';
##manager使用监控用户
mysql> flush privileges; //刷新数据库
#在数据库上添加下列授权(理论上不需要)以主机名授权(MHA检查时是通过主机名的形式)
mysql> grant all privileges on . to 'mha'@'master' identified by 'manager';
mysql> grant all privileges on . to 'mha'@'slave1' identified by 'manager';
mysql> grant all privileges on . to 'mha'@'slave2' identified by 'manager';

在master服务器上查看二进制文件和同步点

mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 1213 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在两台从服务器上设置同步

#在两台从服务器上都执行下列的命令,同步主服务器的日志
mysql> change master to master_host='192.168.52.129',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1213;
mysql> start slave; //开启slave
mysql> show slave status\G; //查看slave
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
mysql> set global read_only=1;
mysql> flush privileges; //刷新数据库

在所有服务器上安装MHA依懒的环镜

[root@master mysql-5.6.36]# yum install epel-release --nogpgcheck -y ##安装源
[root@master mysql-5.6.36]# yum install -y perl-DBD-MySQL \ ##针对MySQL
perl-Config-Tiny \ ##配置文件
perl-Log-Dispatch \ ##日志
perl-Parallel-ForkManager \ ##多线程管理
perl-ExtUtils-CBuilder \ ##扩展工具
perl-ExtUtils-MakeMaker \
perl-CPAN ##程序库

#解压安装node
[root@manager ~]# cd ~
[root@manager ~]# tar zxvf /mnt/mha4mysql-node-0.57.tar.gz
[root@manager ~]# cd mha4mysql-node-0.57/
[root@manager mha4mysql-node-0.57]# perl Makefile.PL ##perl进行编译
[root@manager mha4mysql-node-0.57]# make && make install

在manger服务器上安装manager

#关闭防火墙
[root@manager ~]# systemctl stop firewalld.service
[root@manager ~]# setenforce 0
#解压并安装manager
[root@manager ~]# cd ~
[root@manager ~]# tar zxvf /mnt/mha4mysql-manager-0.57.tar.gz
[root@manager ~]# cd mha4mysql-manager-0.57/
[root@manager mha4mysql-manager-0.57]# perl Makefile.PL ##perl编译
[root@manager mha4mysql-manager-0.57]# make && make install ##编译安装

manager服务器安装后在 usr/local/bin 目录下面会生成几个工具:

  • masterha_check_repl 检查mysql复制状况
  • masterha_master_monitor 检查master是否宕机
  • masterha_check_ssh 检查MHA的SSH配置情况
  • masterha_master_switch 控制故障转移
  • masterha_check_status 检查当前MHA运行状态
  • masterha_conf_host 添加或删除配置的server信息
  • masterha_stop 关闭manager
  • masterha_manager 启动manager的脚本

node安装后在/usr/local/bin下面会生成的几个脚本(通常由MHA Manager的脚本触发,无需人为操作)

  • apply_diff_relay_logs :识别差异的中继日志事件并将其差异的事件应用于其他的 slave;
  • save_binary_logs:保存和复制 master 的二进制日志;
  • filter_mysqlbinlog :去除不必要的 ROLLBACK 事件 (MHA 已不再使用这个工具);
  • purge_relay_logs:清除中继日志(不会阻塞 SQL 线程);

配置无密码访问

##在manager配置所有数据库节点的无密码认证
[root@manager ~]# ssh-keygen -t rsa ##生成秘钥
Enter file in which to save the key (/root/.ssh/id_rsa): ##回车
Enter passphrase (empty for no passphrase): ##回车
Enter same passphrase again: ##回车
[root@manager ~]# ssh-copy-id 192.168.52.129 ##上传到其他服务器
Are you sure you want to continue connecting (yes/no)? yes
root@192.168.52.129's password: ##输入129服务器的密码
[root@manager ~]# ssh-copy-id 192.168.52.130
[root@manager ~]# ssh-copy-id 192.168.52.131
##在master上配置到数据库节点slave1和slave2的无密码认证
[root@master ~]# ssh-keygen -t rsa
[root@master ~]# ssh-copy-id 192.168.52.130
[root@master ~]# ssh-copy-id 192.168.52.131
##在slave1上配置到数据库节点master'和slave2的无密码认证
[root@slave1 ~]# ssh-keygen -t rsa
[root@slave1 ~]# ssh-copy-id 192.168.52.129
[root@slave1 ~]# ssh-copy-id 192.168.52.131
##在slave2上配置到数据库节点slave1和master的无密码认证
[root@slave2 ~]# ssh-keygen -t rsa
[root@slave2 ~]# ssh-copy-id 192.168.52.129
[root@slave2 ~]# ssh-copy-id 192.168.52.130

配置MHA,在manager节点上复制相关脚本到/usr/local目录,并进行配置

[root@manager ~]# cp -ra /root/mha4mysql-manager-0.57/samples/scripts/ /usr/local/bin/
##复制脚本到/usr/local
[root@manager ~]# ls mha4mysql-manager-0.57/samples/scripts/
##生成四个可执行脚本
master_ip_failover:自动切换时 VIP 管理的脚本;
master_ip_online_change:在线切换时 VIP 的管理;
power_manager:故障发生后关闭主机的脚本;
send_report:因故障切换后发送报警的脚本;
##将自动切换时 VIP 管理的脚本复制到 /usr/local/bin/目录下:
[root@manager ~]# cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin/
[root@manager ~]# vim /usr/local/bin/master_ip_failover
##删除所有内容,重新编写 master_ip_failover 脚本
#!/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 $vip = '192.168.52.100';
my $brdc = '192.168.52.255';
my $ifdev = 'ens33';
my $key = '1';
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";
my $exit_code = 0;
#my $ssh_start_vip = "/usr/sbin/ip addr add $vip/24 brd $brdc dev $ifdev label $ifdev:$key;/usr/sbin/arping -q -A -c 1 -I $ifdev $vip;iptables -F;";
#my $ssh_stop_vip = "/usr/sbin/ip addr del $vip/24 dev $ifdev label $ifdev:$key";
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() {
ssh $ssh_user\@$new_master_host \" $ssh_start_vip \";
}

sub stop_vip() {
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";
}

在manager节点上创建MHA软件目录并拷贝配置文件

[root@manager ~]# mkdir /etc/masterha
[root@manager ~]# cp /root/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha/
#编辑配置文件
[root@manager ~]# vim /etc/masterha/app1.cnf
[server default]
#manager配置文件
manager_log=/var/log/masterha/app1/manager.log
#manager日志
manager_workdir=/var/log/masterha/app1
#master保存binlog的位置,这里的路径要与master里配置的bilog的相同
master_binlog_dir=/usr/local/mysql/data
#设置自动failover时候的切换脚本。也就是上边的那个脚本
master_ip_failover_script=/usr/local/bin/master_ip_failover
#设置手动切换时候的切换脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
#这个密码是前文中创建监控用户的那个密码
password=manager
remote_workdir=/tmp
#设置复制用户密码
repl_password=123
#设置复制用户的用户
repl_user=myslave
#设置发生切换后发生报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.52.130 -s 192.168.52.131
#设置故障发生关闭故障脚本主机
shutdown_script=""
#设置ssh的登录用户名
ssh_user=root
#设置监控用户
user=mha

[server1]
hostname=192.168.52.129
port=3306

[server2]
candidate_master=1
#设置为候选master,如果设置该参数以后,发送主从切换以后将会从此从库升级为主库
hostname=192.168.52.130
check_repl_delay=0
port=3306

[server3]
hostname=192.168.52.131
port=3306

在master上配置虚拟ip 启动mha

[root@master mha4mysql-node-0.57]# /sbin/ifconfig ens33:1 192.168.52.100/24

[root@manager scripts]# nohup masterha_manager --conf=/etc/masterha/app1.cnf --remove_dead_master_conf --ignore_last_failover < /dev/null > /var/log/masterha/app1/manager.log 2>&1 &
##查看MHA状态,可以看到当前的master是mysql节点
[root@manager scripts]# masterha_check_status --conf=/etc/masterha/app1.cnf
app1 (pid:43036) is running(0:PING_OK), master:192.168.52.129

故障模拟

[root@manager scripts]# tailf /var/log/masterha/app1/manager.log
##启动监控观察日志记录

##关掉master服务器
[root@master mha4mysql-node-0.57]# pkill -9 mysql

可以看到从库的状态,vip会切换到其中之一的从库上:

[root@slave1 mha4mysql-node-0.57]# ifconfig
ens33: flags=4163 mtu 1500
inet 192.168.52.130 netmask 255.255.255.0 broadcast 192.168.52.255

ens33:1: flags=4163 mtu 1500
inet 192.168.52.100 netmask 255.255.255.0 broadcast 192.168.52.255
ether 00:0c:29:af:94:06 txqueuelen 1000 (Ethernet)

此时,在manager上安装mysql,客户机也可以通过虚拟ip,连接上数据库:

##在vip的数据库服务器上提权
mysql> grant all on . to 'root'@'%' identified by 'abc123';
Query OK, 0 rows affected (0.00 sec)
##在客户机上用虚拟ip进行登录
[root@manager ~]# mysql -uroot -h 192.168.52.100 -p ##指定虚拟ip
Enter password: ##输入密码

MySQL [(none)]>

配置 数据 服务 服务器 数据库 脚本 切换 日志 故障 节点 用户 密码 文件 目录 同步 管理 编译 二进制 事件 环境 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 浪潮服务器山东分销 电子信息技术 网络技术 1u服务器标准尺寸图 希捷服务器硬盘看出厂日期 英业达算力服务器 办公软件开发一般要多少钱 机顶盒服务器无法连接 人大复印资料数据库注册 未转变者进服务器显示名字太短 宁波海曙储存服务器 服务器防火墙安装 加拿大情报机构网络安全评估报告 小学生呼吁网络安全文明上网 盐城多场景视频系统服务器 沈阳中领网络技术有限公司 gome手机服务器异常什么意思 年轻人网络安全课件ppt 电脑版服务器怎么开方舟 海南省亿联互联网科技有限公司 编程软件开发招聘 泰拉瑞亚全物品服务器指令 龙族幻想游戏服务器 服务器安全证书是什么 数据库左边窗口不见了 英国所有的软件开发集团 jsp计算数据库账户余额 linux服务器的优点 首都网络安全日是哪年设立 幼儿园开展网络安全活动新闻 池州物业管理软件开发多少钱
0