MHA高可用架构

发布于:2025-09-08 ⋅ 阅读:(22) ⋅ 点赞:(0)
  1. MHA(Master HA)是一款开源的 MySQL 的高可用程序,它为 MySQL 主从复制架构提供了automating master failover 功能。MHA 在监控到 master 节点故障时,会提升其中拥有最新数据的slave 节点成为新的master 节点,在此期间,MHA 会通过其它从节点获取额外信息来避免一致性方面的问题。MHA 还提供了 master 节点的在线切换功能,即按需切换 master/slave 节点。 MHA 是由日本人 yoshinorim(原就职于DeNA现就职于FaceBook)开发的比较成熟的 MySQL 高可用方案。MHA 能够在30秒内实现故障切换,并能在故障切换中,最大可能的保证数据一致性。
  2. MHA 服务有两种角色, MHA Manager(管理节点)和 MHA Node(数据节点): MHA Manager:通常在一台独立的机器上管理多个master-slave集群,也可以部署在一台slave节点上。 MHA node:MHA Node运行在每台MySQL服务器上,MHA Manager会定时探测集群中的master节点,当master出现故障时,它可以自动将最新数据的slave提升为新的master,然后将所有其他的slave重新指向新的master。整个故障转移过程对应用程序完全透明。

MHA工作原理:

  • 目前MHA主要支持一主多从的架构,要搭建MHA,要求一个复制集群必须最少有3台数据库服务器,一主二从,即一台充当Master,一台充当备用Master,一台充当从库。

  • MHA Node 运行在每台 MySQL 服务器上。

  • MHAManager 会定时探测集群中的master 节点。

  • 当master 出现故障时,它可以自动将最新数据的slave 提升为新的master

  • 然后将所有其他的slave 重新指向新的master,VIP自动漂移到新的master。

  • 整个故障转移过程对应用程序完全透明。

准备工作

机器名称 ip 版本 说明
manager 192.168.1.200 8.0.40 Source distribution manager控制器
master 192.168.1.128 8.0.40 Source distribution 数据库主服务器
rep1 192.168.1.129 8.0.40 Source distribution 数据库从服务器
rep2 192.168.1.130 8.0.40 Source distribution 数据库从服务器
  • 配置master,rep1,rep2的/etc/my.cnf文件

  • 然后三台机器重新启动mysql
/etc/init.d/mysqld restart

配置一主多从复

主库配置

master节点上,mha只支持mysql_native_password密码认证插件

在主机上创建认证用户并赋予权限

create user 'rep'@'%' identified WITH mysql_native_password  by '123';
grant  replication slave on *.* to 'rep'@'%';

两台从库的配置

CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.1.128',
SOURCE_USER='rep',
SOURCE_PASSWORD='123',
master_auto_position=1,
SOURCE_SSL=1;

开启从库开关

start replica;

查看从库的主从同步状态

show replica status;

  • 四台主机配置dns解析

配置MHA

首先安装HMA的包

https://code.google.com/archive/p/mysql-master-ha/

github下载地址:

Release mha4mysql-manager-0.58 · yoshinorim/mha4mysql-manager · GitHub

在manager中配置:

  • 上传HMA的压缩文件

  • 解压缩HMA的压缩文件
unzip MHA-7.zip

  • 下载MHA的包
yum install ./*.rpm -y

  • master,rep1,rep2需要下载node节点,都在MHA的压缩包内,可以通过scp的命令,从manager的机器内传到这三台主机内
for i in {master,rep1,rep2};do scp mha4mysql-node-0.58-0.el7.centos.noarch.rpm root@$i:/root;done

  • 查看文件是否传输成功

  • master,rep1,rep2下载传过来的node节点包

master的用户设置

  • 设置可以远程访问mysql的用户,并设置管理员权限。
  • 只需要在master上运行即可
create user 'mhaadm'@'%' identified WITH mysql_native_password  by '123';
grant all on *.* to 'mhaadm'@'%';

  • MHA集群中的各节点彼此之间均需要基于ssh互信通信,以实现远程控制及数据管理功能。配置好四台主机的公私要方便连接
  1. 所有节点生成公私钥(manager,master,rep1,rep2)
ssh-keygen

  • 将所有节点的公钥上传至manager节点,最后将manager节点的authorized_keys分发到其他节点
ssh-copy-id root@manager
for i in {master,rep1,rep2};do scp /root/.ssh/authorized

  • 测试节点是否可以免密登录
for i in {master,rep1,rep2};do ssh $i hostname ;done

  • 在manager上创建配置文件目录--用于记录mha的配置文件和日志文件
mkdir -p /etc/mha /var/log/mha/app1

  • 配置mha的配置
vim /etc/mha/app1.cnf

  • 输入如下命令检测各节点间ssh互信通信配置是否ok
  •  masterha_check_ssh --conf=/etc/mha/app1.cnf

  • 检查mysql复制集群的连接配置参数是否ok
master_check_repl --conf=/etc/mha/app1.cnf

测试master故障手动配置mha来转移master

  • 首先停止master的mysql
/etc/init.d/mysqld stop

手动配置mha控制master转移到rep1上

  • 在manager上配置
masterha_master_switch --master_state=dead --conf=/etc/mha/app1.cnf --dead_master_host=192.168.1.128 --dead_master_port=3306 --new_master_host=192.168.1.129 --new_master_port=3306 --ignore_last_failover

  • 在rep1上查看一下--rep1的从库情况--master成功转移到rep1上
show replicas;

  • 恢复MySQL的故障节点使master重新加入集群
[root@master mysql]# /etc/init.d/mysqld start
#将该主机重新加入集群中
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.168.129',
SOURCE_USER='rep',
SOURCE_PASSWORD='123',
master_auto_position=1,
SOURCE_SSL=1;
Query OK, 0 rows affected, 3 warnings (0.00 sec)

mysql> start replica;
Query OK, 0 rows affected (0.01 sec)

mysql> show replica status\G
*************************** 1. row ***************************
             Replica_IO_State: Waiting for source to send event
                  Source_Host: 192.168.168.129
                  Source_User: rep
                  Source_Port: 3306
                Connect_Retry: 60
              Source_Log_File: binlog.000003
          Read_Source_Log_Pos: 1249
               Relay_Log_File: relay-log.000003
                Relay_Log_Pos: 451
        Relay_Source_Log_File: binlog.000003
           Replica_IO_Running: Yes
          Replica_SQL_Running: Yes

配置mha故障自动转移master

  • 删除锁文件,如果不删除的话mha无法故障转移成功
rm -rf /var/log/mha/app1/app1.failover.complete

  • 开启mha的检测
masterha_manager --conf=/etc/mha/app1.cnf

  • 查看mha的状态-----在复制一台manager查看
 masterha_check_status --conf=/etc/mha/app1.cnf

  • 模拟主mysql宕机---关闭rep1的数据库

  • 当故障转移完成后,mha-manager将会自动停止运行
  • 查看转移日志
cat /var/log/mha/app1/manager.log

  • 查看一master的机器的从库情况--此时rep1宕机只有rep2一台从库

  • 删除锁文件
rm -rf  /var/log/mha/app1/app1.failover.complete
[root@rep1 ~]# /etc/init.d/mysqld  start
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.168.128',
SOURCE_USER='rep',
SOURCE_PASSWORD='123',
master_auto_position=1,
SOURCE_SSL=1;
mysql> start replica;

配置VIP

ip配置可以采用两种方式,一种通过keepalived的方式管理虚拟ip的浮动;另外一种通过脚本方式启动虚拟ip的方式 (即不需要keepalived或者heartbeat类似的软件)。为了防止脑裂发生,推荐生产环境采用脚本的方式来管理虚拟ip,而不是使用keepalived来完成

  • 在manager机器上编辑脚本
vim /usr/local/bin/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.1.88/24';
my $ssh_start_vip = "/sbin/ip a add $vip dev ens32";
my $ssh_stop_vip = "/sbin/ip a del $vip dev ens32";

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() {
  return 0 unless ($ssh_user);
  `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";
}
  • 给/usr/local/bin/master_ip_failover增加权限
chmod +x /usr/local/bin/master_ip_failover
  • 更改manager配置文件
vim /etc/mha/app1.cnf
[server default]
master_ip_failover_script=/usr/local/bin/master_ip_failover
user=mhaadm
password=123
manager_workdir=/var/log/mha/app1
manager_log=/var/log/mha/app1/manager.log
ssh_user=root
repl_user=rep
repl_password=123
ping_interval=1
[server1]
hostname=192.168.1.128
ssh_port=22
candidate_master=1
[server2]
hostname=192.168.1.129
ssh_port=22
candidate_master=1
[server3]
hostname=192.168.1.130
ssh_port=22
no_master=1

  • 在主库master上手动配置第一次的VIP地址
ip address add 192.168.1.88/24 dev ens32

先检查一下三台主机的ssh通信情况和MySQL集群连接配置的参数

  • 在mha-manager上启动MHA
masterha_manager --conf=/etc/mha/app1.cnf --ignore_last_failover

模拟故障停掉master机器

/etc/init.d/mysqld stop

  • 常看IP是否漂移
  • 首先查看master机器是否还有VIP---不存在

  • 在查看一下rep1的IP是否存在VIP---存在VIP----VIP在mha的控制下从master转移到rep1/


网站公告

今日签到

点亮在社区的每一天
去签到