MySQL MHA高可用
MySQL MHA高可用解决方案详解
- 前言
- 一、什么是MHA
- 1.1 MHA的组成
- 1.2 MHA的特点
- 1.3 MHA工作原理
- 二、搭建MySQL MHA
- 2.1 搭建思路
- 2.2 环境
- 2.3 准备工作
- 2.4Manager与Node工具使用
- 2.5 配置无密码认证
- 2.6在Manager节点上配置MHA
- 2.6 测试与启动
- 2.7 MHA模拟故障
- 结语
前言
在当今数字化时代,数据库作为信息系统的核心组件,其高可用性至关重要。任何数据库服务的中断都可能导致业务停滞、数据丢失,甚至造成严重的经济损失和声誉损害。MySQL作为全球最受欢迎的开源关系型数据库之一,被广泛应用于各类业务系统中。然而,MySQL本身的高可用性方案相对基础,特别是在面对主节点故障时,如何快速、安全地进行故障切换,同时保证数据一致性,是企业面临的重要挑战。
本文将详细介绍MySQL MHA(Master High Availability)这一优秀的MySQL高可用解决方案。MHA能够有效解决MySQL单点故障问题,在故障切换过程中实现快速自动恢复,最大程度地保证数据一致性,真正实现数据库的高可用性。我们将从MHA的基本概念出发,逐步深入探讨其组成架构、核心特点、工作原理,并通过详细的实战步骤指导您完成MHA环境的搭建与故障模拟,帮助您全面掌握这一强大的高可用解决方案。
一、什么是MHA
MHA(Master High Availability)是一套专为MySQL设计的高可用环境下故障切换和主从复制的优秀软件。它的核心使命就是解决MySQL的单点故障问题,确保数据库服务的持续可用性。
在传统的MySQL主从架构中,当主库(Master)发生故障时,如果没有有效的自动化处理机制,数据库服务将面临中断风险,需要人工介入进行故障排查和恢复,这不仅耗时耗力,还可能延长服务不可用的时间窗口。MHA的出现正是为了解决这一痛点。
MHA的突出优势在于其快速的故障切换能力。在MySQL故障切换过程中,MHA能够做到在0-30秒内自动完成故障切换操作,这一速度远快于传统的手工切换方式,极大地减少了服务中断时间。更为重要的是,MHA在故障切换的过程中能够最大程度上保证数据的一致性,通过一系列智能的日志处理和数据同步机制,确保切换后的新主库与其他从库保持数据一致,达到真正意义上的高可用。
1.1 MHA的组成
MHA架构由两个核心组件构成,它们协同工作,共同实现高可用的目标:
MHA Node(数据节点)
MHA Node运行在每台MySQL服务器上,包括主库和所有从库。它是MHA体系的基础组件,负责执行具体的数据操作任务,如二进制日志的保存、中继日志的应用等。MHA Node是轻量级的代理程序,通过与MySQL服务器交互,实现对数据库状态的监控和数据操作的执行。
MHA Manager(管理节点)
MHA Manager可以单独部署在一台独立的机器上,也可以部署在一台slave节点上。它承担着整个MHA系统的"大脑"角色,负责管理和协调整个高可用环境。
MHA Manager的主要职责包括:
- 定时探测集群中的master节点:通过定期的健康检查,实时监控主库的运行状态。
- 自动故障检测与切换:当检测到master出现故障时,MHA Manager能够自动触发故障切换流程。
- 智能主库提升:将最新数据的slave提升为新的master,确保业务可以快速恢复。
- 从库重定向:将所有其他的slave重新指向新的master,维持复制拓扑的完整性。
整个故障转移过程对应用程序完全透明,应用程序无需修改任何配置即可继续访问数据库服务。
1.2 MHA的特点
MHA之所以成为MySQL高可用领域的优秀解决方案,得益于其一系列精心设计的核心特点:
自动故障切换与数据保护
在自动故障切换过程中,MHA试图从宕机的主服务器上保存二进制日志(binlog),这一机制能够最大程度地保证数据不丢失。即使在主库突然崩溃的情况下,MHA也能尽可能地捕获和保存最后的操作日志,为数据恢复提供基础。
半同步复制支持
使用半同步复制技术,可以大大降低数据丢失的风险。半同步复制确保至少有一个从库接收到了主库的确认,然后再向客户端返回成功响应。如果只有一个slave已经收到了最新的二进制日志,MHA可以将这些最新的二进制日志应用于其他所有的slave服务器上,从而保证所有节点的数据一致性。
架构支持
目前MHA支持一主多从架构,最少需要三台服务器,即一主两从的配置。这种架构设计既保证了高可用性,又提供了足够的冗余度。MHA Manager具备管理多组主从复制的能力,可以同时监控和管理多个MySQL集群,满足企业级复杂环境的需求。
1.3 MHA工作原理
MHA的高效运作基于一套精密的工作流程,其工作原理可以总结为以下关键步骤:
- 保存二进制日志事件:从宕机崩溃的master保存二进制日志事件(binlog events),这是数据恢复的基础。
- 识别最新更新:识别含有最新更新的slave日志,确定数据最完整的从库。
- 应用中继日志差异:应用差异的中继日志(relay log)到其他的slave,确保从库之间的数据一致性。
- 应用主库二进制日志:应用从master保存的二进制日志事件,补充可能缺失的操作。
- 提升新主库:提升一个slave为新的master,作为服务的核心节点。
- 重定向复制:使其他的slave连接新的master进行复制,重建复制拓扑。
这一系列流程环环相扣,确保了在主库故障后,系统能够快速、安全地恢复服务,同时最大限度地保证数据的一致性和完整性。
二、搭建MySQL MHA
下面我们将通过详细的步骤,指导您完成MySQL MHA环境的搭建。整个搭建过程包括环境准备、软件安装、配置调试和故障模拟等环节。
2.1 搭建思路
我们的搭建思路分为两个主要部分:
- MHA架构搭建:包括数据库安装、一主两从复制环境的构建,以及MHA组件的安装和配置。
- 故障模拟:模拟主库失效场景,观察备选主库如何接管服务,以及原故障主库恢复后如何重新加入集群。
2.2 环境
我们使用以下服务器环境进行搭建:
- MHA manager节点:CentOS7.9(64位),IP为192.168.10.50,安装MHA node和manager组件。
- Master节点:CentOS7.9(64位),IP为192.168.10.10,安装mysql5.7和MHA node组件。
- Slave1节点:CentOS7.9(64位),IP为192.168.10.30,安装mysql5.7和MHA node组件。
- Slave2节点:CentOS7.9(64位),IP为192.168.10.40,安装mysql5.7和MHA node组件。
2.3 准备工作
在开始搭建前,需要进行一系列的基础准备工作:
#关闭防火墙和SELinux:确保网络通信不受安全策略的限制。
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
#安装MySQL 5.7:在所有节点上安装MySQL数据库服务。
#配置主机名:为每个节点设置唯一的主机名,便于识别和管理。
hostnameclt set-hostname [名称]
bash
#配置MySQL主配置文件:根据节点角色设置不同的MySQL参数,如server-id、log-bin等。
vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
log-slave-updates = true
systemctl restart mysqld
##Slave1 节点##
vim /etc/my.cnf
server-id = 2 #三台服务器的 server-id 不能一样
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
systemctl restart mysqld
###Slave2 节点##
vim /etc/my.cnf #三台服务器的 server-id 不能一样
server-id = 3
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
systemctl restart mysqld
#创建软链接:简化MySQL命令的调用。
ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/
#配置一主两从复制:建立主从复制关系,确保数据能够从主库同步到从库。
mysql -uroot -p
grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456'; #从数据库同步使用
grant all privileges on *.* to 'mha'@'192.168.10.%' identified by 'manager'; #manager 使用
grant all privileges on *.* to 'mha'@'master' identified by 'manager'; #防止从库通过主机名连接不上主库
grant all privileges on *.* to 'mha'@'slave1' identified by 'manager';
grant all privileges on *.* to 'mha'@'slave2' identified by 'manager';
flush privileges;
#查询master 文件及节点
show master status;
#在 Slave1、Slave2 节点执行同步操作
change master to master_host='192.168.10.10',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=1745;
start slave;
set global read_only=1;
#主数据库节点
create database test_db;
use test_db;
create table test(id int);
insert into test(id) values (1);
#安装MHA所有组件与测试(全部节点)
yum install epel-release --nogpgcheck -y
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
#MHA的安装分为Manager和Node两个层面:
#安装MHA软件
#1. 安装依赖环境:包括epel源和一系列Perl模块,这些是MHA运行的基础依赖。
yum install epel-release --nogpgcheck -y
yum install -y perl-DBD-MySQL \
perl-Config-Tiny \
perl-Log-Dispatch \
perl-Parallel-ForkManager \
perl-ExtUtils-CBuilder \
perl-ExtUtils-MakeMaker \
perl-CPAN
#2. 安装MHA Node组件:在所有服务器上安装MHA的Node组件,这是数据节点的基础。
cd /opt
tar zxvf mha4mysql-node-0.57.tar.gz
cd mha4mysql-node-0.57
perl Makefile.PL
make && make install
#3. 安装MHA Manager组件:在Manager节点上安装Manager组件,负责集群的管理和协调。
cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install
2.4Manager与Node工具使用
MHA提供了一系列实用工具,用于监控、管理和故障处理:
- Manager组件工具:包括集群状态检查、主库监控、故障切换控制等。
- Node组件工具:由Manager脚本触发,负责具体的数据操作任务。
2.5 配置无密码认证
为了实现节点间的自动化通信,需要在所有服务器间配置SSH无密码认证,包括Manager到所有数据库节点,以及Master到Slave节点的认证。
#在manager 节点上配置到所有数据库节点的无密码认证
ssh-keygen -t rsa #一路按回车键
ssh-copy-id 192.168.10.14
ssh-copy-id 192.168.10.15
ssh-copy-id 192.168.10.16
#在master上配置到数据库节点 slave1 和 slave2 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.10.14
ssh-copy-id 192.168.10.15
#在slave1上配置到数据库节点 master 和 slave2 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.10.16
ssh-copy-id 192.168.10.15
#在 slave2上配置到数据库节点 master 和 slave1 的无密码认证
ssh-keygen -t rsa
ssh-copy-id 192.168.10.16
ssh-copy-id 192.168.10.14
2.6在Manager节点上配置MHA
- 配置VIP管理脚本:用于故障切换时虚拟IP的自动迁移。
#在 manager 节点上复制相关脚本到/usr/local/bin 目录
cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
#//拷贝后会有四个执行文件
ll /usr/local/bin/scripts/
----------------------------------------------------------------------------------------------------------
master_ip_failover #自动切换时 VIP 管理的脚本
master_ip_online_change #在线切换时 vip 的管理
power_manager #故障发生后关闭主机的脚本
send_report #因故障切换后发送报警的脚本
----------------------------------------------------------------------------------------------------------
#复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,这里使用master_ip_failover脚本来管理 VIP 和故障切换
cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin
#修改内容如下:(删除原有内容,直接复制并修改vip相关参数)
vim /usr/local/bin/master_ip_failover # ste paste
#!/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.10.200'; #指定vip的地址
my $brdc = '192.168.10.255'; #指定vip的广播地址
my $ifdev = 'ens33'; #指定vip绑定的网卡
my $key = '1'; #指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip"; #代表此变量值为ifconfig ens33:1 192.168.10.200
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down"; #代表此变量值为ifconfig ens33:1 192.168.10.200 down
my $exit_code = 0; #指定退出状态码为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 \"`;
}
## A simple system call that disable the VIP on the old_master
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";
}
2. 创建MHA配置文件:定义集群节点信息、监控参数和故障切换策略。
[server default]
manager_log=/var/log/masterha/app1/manager.log
manager_workdir=/var/log/masterha/app1
master_binlog_dir=/usr/local/mysql/data
master_ip_failover_script=/usr/local/bin/master_ip_failover
master_ip_online_change_script=/usr/local/bin/master_ip_online_change
password=manager
ping_interval=1
remote_workdir=/tmp
repl_password=123456
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.10.30 -s 192.168.10.40
shutdown_script=""
ssh_user=root
user=mha[server1]
hostname=192.168.10.10
port=3306[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.10.30
port=3306[server3]
hostname=192.168.10.40
port=3306
- 配置虚拟IP:在Master节点上手动开启虚拟IP,用于故障切换时的服务访问。
ifconfig ens33:1 192.168.10.200/24
2.6 测试与启动
- 测试SSH无密码认证:确保Manager能够无密码访问所有节点。
masterha_check_ssh -conf=/etc/masterha/app1.cnf
2. 测试MySQL主从连接:验证主从复制状态是否正常。
masterha_check_repl -conf=/etc/masterha/app1.cnf
3. 启动MHA服务:在Manager节点上启动MHA管理进程,开始监控集群状态。
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状态:通过日志和状态命令,确认MHA运行正常,主库识别正确。
masterha_check_status --conf=/etc/masterha/app1.cnf
2.7 MHA模拟故障
搭建完成后,我们可以进行故障模拟,验证MHA的故障切换能力:
- 监控日志:在Manager节点上实时监控MHA日志,观察系统状态变化。
tail -f /var/log/masterha/app1/manager.log
- 模拟主库故障:停止Master节点的MySQL服务,触发故障切换。
systemctl stop mysqld
3. 观察自动切换:MHA应自动将最优的Slave提升为新的Master,并重新配置其他Slave的复制关系。
4. 验证服务可用性:检查新Master是否正常提供服务,应用是否能够无缝连接。
- 故障恢复:修复原Master节点,将其重新加入集群作为Slave。
systemctl restart mysqld #重启数据库
show master status; #查看主数据库信息
change master to master_host='192.168.10.30',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=1745; #配置主从复制
start slave;
show slave status\G #查看从复制状态,双YES正常
vim /etc/masterha/app1.cnf
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的故障切换算法会智能地选择最优的备选主库,考虑数据一致性、复制延迟和配置权重等因素,确保切换后的集群状态最优。
结语
通过本文的详细介绍,相信您已经对MySQL MHA高可用解决方案有了全面而深入的了解。MHA作为MySQL生态中成熟的高可用方案,通过其快速的故障切换能力、可靠的数据一致性保证和灵活的架构设计,为企业的数据库服务提供了坚实的可用性保障。
在实际应用中,MHA不仅能够应对计划内的维护操作,更能有效处理各种意外故障场景,确保数据库服务的高可用性。通过合理的架构设计和细致的配置调优,MHA可以满足不同规模企业对数据库高可用的多样化需求。
数据库高可用是一个持续优化的过程,除了技术方案的选型与实施,还需要配合完善的监控体系、规范的操作流程和定期的演练测试。建议读者在实际部署MHA时,结合企业具体业务需求,充分考虑网络环境、硬件配置和运维能力等因素,制定最适合的高可用方案。
希望本文能够为您的MySQL高可用建设提供有价值的参考,助力您的业务系统实现持续稳定运行。记住,高可用不仅是技术方案,更是一种业务承诺——确保您的服务始终在线,数据永远安全。