mysql-高可用架构:MHA

mysql-高可用架构:MHA

1. MHA简介

MHA(Master High Availability)是由日本人yoshinorim开发的一款成熟且开源的MySQL高可用程序,它实现了MySQL主从环境下MASTER宕机后能够自动进行单次故障转移的功能,其本身由perl语言编写,安装方便使用简单。

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

1.1 MHA 工作流程

以下是MHA的工作流程,Manager节点通过masterha_manager脚本启动MHA后会先进行检查工作:

  • Manager节点通过masterha_check_ssh脚本检查各节点的互信配置
  • Manager节点通过masterha_check_repl脚本检查主从之间的复制情况

检查工作均完成且确认无误后,Manager节点会进行监控工作:

  • Manager节点通过masterha_master_monitor对主库不断的进行心跳检测,主库3次无响应后会认为其以宕机

当主库宕机后,会开始故障转移工作,首先会对SLAVE进行选主,有以下3种算法:

  • 读取Manager配置文件,判断是否有强制选主的Slave
  • 自动判断目前已有从库的日志量,将最接近主库日志量的从库选为新的主库
  • 根据配置文件中先后顺序进行选主

当选主完成后,Manager节点会再次通过SSH链接已宕机主库,有以下2种情况发生:

  • 已宕机主库的SSH能够链接,表明MySQL服务是由逻辑因素所导致的宕机,此时Manager会通过save_binary_logs脚本,计算各个从库(包括新主库)与已宕机主库之间binlog差异,将已宕机主库的binlog位置找出来并进行截取、分发到各个从库上进行数据对齐,确保数据一致性
  • 已宕机主库的SSH不能链接,表明MySQL服务是由物理因素所导致的宕机,此时Manager会通过apply_diff_relay_logs脚本,计算各个从库relay-log的差异,将差异较大的从库与新主库进行relay-log对齐,确保数据一致性

当所有库的数据一致性被确保之后,所有从库都将会与新主库建立主从关系,同时旧的已宕机主库信息将会从Manager项目配置文件中移除,至此整个MHA软件服务结束,Manager不会再对Node进行管理,接下来需要管理员手动对已宕机主库进行排查恢复,并且手动搭建旧主库与新主库之间的主从关系然后重新启动整个MHA服务。

MHA高可用架构 – 知乎 (zhihu.com)

2. MHA实操配置

2.1 环境配置

本次所用主机系统版本均为centos7,mysql版本为5.7.37

服务列表 IP地址 mysql主节点(Master) 192.168.80.20 mysql从节点1 192.168.80.25 mysql从节点2 192.168.80.30 MHA Manager 192.168.80.35

2.2 搭建步骤

1.首先关闭所有虚拟机的防火墙与SElinux。

systemctl stop firewalld
systemctl disable firewalld
setenforce 0

2.配置主机名

为方便操作时区分各个主机,分别设置Master,Slaver1,Slaver2节点主机名称为mysql_master,mysql_slaver1,mysql_slaver2.

hostnamectl set-hostname mysql_master
hostnamectl set-hostname mysql_slaver1
hostnamectl set-hostname mysql_slaver2

su

3.修改 Master、Slaver1、Slaver2 节点的 Mysql主配置文件/etc/my.cnf,配置主从同步。

##Master 节点##
vim /etc/my.cnf
[mysqld]
server-id = 1
log_bin = master-bin
log-slave-updates = true

systemctl restart mysqld

##Slave1、Slave2 节点##
vim /etc/my.cnf
server-id = 2 / 3                       #三台服务器的 server-id 不能一样
log_bin = master-bin
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index

systemctl restart mysqld

4.在 Master、Slave1、Slave2 节点上都创建两个软链接

ln -s /usr/local/mysql/bin/mysql /usr/sbin/
ln -s /usr/local/mysql/bin/mysqlbinlog /usr/sbin/

5.配置 mysql 一主两从

(1)权限配置

mysql -uroot -pabc123
grant replication slave on *.* to 'myslave'@'192.168.80.%' identified by '123';     #从数据库同步使用
grant all privileges on *.* to 'mha'@'192.168.80.%' identified by 'manager';        #manager 使用

grant all privileges on *.* to 'mha'@'mysql_master' identified by 'manager';                #防止从库通过主机名连接不上主库
grant all privileges on *.* to 'mha'@'mysql_slaver1' identified by 'manager';
grant all privileges on *.* to 'mha'@'mysql_slaver2' identified by 'manager';
flush privileges;

(2)在 Master 节点查看二进制文件和同步点

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

(3)在 Slave1、Slave2 节点执行同步操作

(3)在 Slave1、Slave2 节点执行同步操作,注意log_pos需要与主的查询一致
change master to master_host='192.168.80.20',master_user='myslave',master_password='123',master_log_file='master-bin.000001',master_log_pos=1765;

start slave;

(4)在 Slave1、Slave2 节点查看数据同步结果

show slave status\G
//确保 IO 和 SQL 线程都是 Yes,代表同步正常。
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

(5) Slave1、Slave2开启只读模式。

set global read_only=1;

(6)插入数据测试数据库同步

##在 Master 主库插入条数据,测试是否同步##
create database canyun_db;
use canyun_db;
create table test(id int);
insert into test(id) values (1);

##SLAVER1,2 查看是否完成同步
select * from canyun_db.test;

6.安装 MHA 软件
(1)所有服务器(包括MHA Manager)上都安装 MHA 依赖的环境,首先安装 epel 源

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 组件

对于每个操作系统版本不一样,这里 CentOS7.6 必须选择 0.57 版本。
在所有服务器上必须先安装 node 组件,最后在 MHA-manager 节点上安装 manager 组件,因为 manager 依赖 node 组件。

事先准备软件包到/opt目录

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 组件

cd /opt
tar zxvf mha4mysql-manager-0.57.tar.gz
cd mha4mysql-manager-0.57
perl Makefile.PL
make && make install

7.在所有服务器上配置无密码认证
(1)在 manager 节点上配置到所有数据库节点的无密码认证

ssh-keygen -t rsa               #一路按回车键
ssh-copy-id 192.168.80.20
ssh-copy-id 192.168.80.25
ssh-copy-id 192.168.80.30

(2)在 master上配置到数据库节点 slaver1 和 slaver2 的无密码认证

ssh-keygen -t rsa
ssh-copy-id 192.168.80.25
ssh-copy-id 192.168.80.30

(3)在 slaver1上配置到数据库节点 master 和 slaver2 的无密码认证

ssh-keygen -t rsa
ssh-copy-id 192.168.80.20
ssh-copy-id 192.168.80.30

(4)在 slaver2 上配置到数据库节点 master和 slaver1 的无密码认证

ssh-keygen -t rsa
ssh-copy-id 192.168.80.20
ssh-copy-id 192.168.80.25
  1. 在 manager 节点上配置 MHA

(1)在 manager 节点上复制相关脚本到/usr/local/bin 目录

cp -rp /opt/mha4mysql-manager-0.57/samples/scripts /usr/local/bin
//拷贝后会有四个执行文件
ll /usr/local/bin/scripts/

(2)复制上述的自动切换时 VIP 管理的脚本到 /usr/local/bin 目录,这里使用master_ip_failover脚本来管理 VIP 和故障切换

cp /usr/local/bin/scripts/master_ip_failover /usr/local/bin

(3)修改内容如下:(删除原有内容,直接复制并修改vip相关参数。可在拷贝前输入 :set paste 解决vim粘贴乱序问题)

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.80.200';                                 #指定vip的地址
my $brdc = '192.168.80.255';                                #指定vip的广播地址
my $ifdev = 'ens33';                                        #指定vip绑定的网卡
my $key = '1';                                              #指定vip绑定的虚拟网卡序列号
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";       #代表此变量值为ifconfig ens33:1 192.168.80.200
my $ssh_stop_vip = "/sbin/ifconfig ens33:$key down";        #代表此变量值为ifconfig ens33:1 192.168.80.200
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";
}

(4)创建 MHA 软件目录并拷贝配置文件,这里使用app1.cnf配置文件来管理 mysql 节点服务器

mkdir /etc/masterha
cp /opt/mha4mysql-manager-0.57/samples/conf/app1.cnf /etc/masterha

vim /etc/masterha/app1.cnf                      #删除原有内容,直接复制并修改节点服务器的IP地址
[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=123
repl_user=myslave
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.80.25 -s 192.168.80.30
shutdown_script=""
ssh_user=root
user=mha

[server1]
hostname=192.168.80.20
port=3306

[server2]
candidate_master=1
check_repl_delay=0
hostname=192.168.80.25
port=3306

[server3]
hostname=192.168.80.30
port=3306
_____________________________________配置文件解释————————————————————————————————————---
[server default]
manager_log=/var/log/masterha/app1/manager.log       #manager日志
manager_workdir=/var/log/masterha/app1.log         #manager工作目录
master_binlog_dir=/usr/local/mysql/data/          #master保存binlog的位置,这里的路径要与master里配置的binlog的路径一致,以便MHA能找到
master_ip_failover_script=/usr/local/bin/master_ip_failover  #设置自动failover时候的切换脚本,也就是上面的那个脚本
master_ip_online_change_script=/usr/local/bin/master_ip_online_change  #设置手动切换时候的切换脚本
password=manager            #设置mysql中root用户的密码,这个密码是前文中创建监控用户的那个密码
ping_interval=1             #设置监控主库,发送ping包的时间间隔,默认是3秒,尝试三次没有回应的时候自动进行failover
remote_workdir=/tmp         #设置远端mysql在发生切换时binlog的保存位置
repl_password=123           #设置复制用户的密码
repl_user=myslave           #设置复制用户的用户
report_script=/usr/local/send_report     #设置发生切换后发送的报警的脚本
secondary_check_script=/usr/local/bin/masterha_secondary_check -s 192.168.80.20 -s 192.168.80.30    #指定检查的从服务器IP地址
shutdown_script=""          #设置故障发生后关闭故障主机脚本(该脚本的主要作用是关闭主机防止发生脑裂,这里没有使用)
ssh_user=root               #设置ssh的登录用户名
user=mha                    #设置监控用户root

[server1]
hostname=192.168.80.10
port=3306

[server2]
hostname=192.168.80.20
port=3306
candidate_master=1
#设置为候选master,设置该参数以后,发生主从切换以后将会将此从库提升为主库,即使这个从库不是集群中最新的slave

check_repl_delay=0
#默认情况下如果一个slave落后master 超过100M的relay logs的话,MHA将不会选择该slave作为一个新的master,
因为对于这个slave的恢复需要花费很长时间;通过设置check_repl_delay=0,MHA触发切换在选择一个新的master的
时候将会忽略复制延时,这个参数对于设置了candidate_master=1的主机非常有用,因为这个候选主在切换的过程中一定是新的master

[server3]
hostname=192.168.80.30
port=3306

9.第一次配置需要在 Master 节点上手动开启虚拟IP

/sbin/ifconfig ens33:1 192.168.80.200/24

10.在 manager 节点上测试 ssh 无密码认证,如果正常最后会输出 successfully,如下所示。

masterha_check_ssh -conf=/etc/masterha/app1.cnf

[root@localhost mha4mysql-manager-0.57]# masterha_check_ssh -conf=/etc/masterha/app1.cnf
Sat Jun 11 00:30:43 2022 - [warning] Global configuration file /etc/masterha_default.cnf not found. Skipping.

Sat Jun 11 00:30:43 2022 - [info] Reading application default configuration from /etc/masterha/app1.cnf..

Sat Jun 11 00:30:43 2022 - [info] Reading server configuration from /etc/masterha/app1.cnf..

Sat Jun 11 00:30:43 2022 - [info] Starting SSH connection tests..

Sat Jun 11 00:30:45 2022 - [debug]
.............................................................

Sat Jun 11 00:30:51 2022 - [info] All SSH connection tests passed successfully.

11.在 manager 节点上测试 mysql 主从连接情况,最后出现 MySQL Replication Health is OK 字样说明正常。如下所示。

masterha_check_repl -conf=/etc/masterha/app1.cnf
....................................

IN SCRIPT TEST====/sbin/ifconfig ens33:1 down==/sbin/ifconfig ens33:1 192.168.80.200===

Checking the Status of the script.. OK
Sat Jun 11 00:34:12 2022 - [info]  OK.

Sat Jun 11 00:34:12 2022 - [warning] shutdown_script is not defined.

Sat Jun 11 00:34:12 2022 - [info] Got exit code 0 (Not master dead).

MySQL Replication Health is OK.

12.在 manager 节点上启动 MHA

`bash
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 &

●使用&后台运行程序:结果会输出到终端;使用Ctrl+C发送SIGINT信号,程序免疫;关闭session发送SIGHUP信号,程序关闭。
●使用nohup运行程序:结果默认会输出到nohup.out;使用Ctrl+C发送SIGINT信号,程序关闭;关闭session发送SIGHUP信号,程序免疫。
●使用nohup和&配合来启动程序nohup ./test &:同时免疫SIGINT和SIGHUP信号。

Original: https://www.cnblogs.com/Canyun-blogs/p/16368975.html
Author: 残-云
Title: mysql-高可用架构:MHA

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/606876/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 路由层

    目录 django请求生命周期流程图 *路由层相关知识 内容 django请求生命周期流程图 整体概括请求的走向以及django的核心组成部分 路由匹配 路由匹配的特点 只要匹配上…

    Linux 2023年6月7日
    0117
  • Shell命令

    1.shell命令的执行机制:fork+exec执行命令(任何的shell都会执行) 2.shell中的用户输入处理 1 命令行参数:选项、参数 2 运行时输入 3 read命令:…

    Linux 2023年6月6日
    0114
  • 测试代理的墙是否是通的

    curl -v -x 代理ip:端口 目的ip:端口通过代理访问对方wget “http://目的IP:端口” -e use_proxy=yes -e ht…

    Linux 2023年6月14日
    0119
  • 堆栈

    目录: 9、【剑指Offer学习】【面试题09:用两个栈实现队列】 30、【剑指Offer学习】【面试题30:包含min函数的栈】 31、【剑指Offer学习】【面试题31:栈的压…

    Linux 2023年6月13日
    0126
  • 在linux中使用tcpdump抓包的方法:

    在linux中使用tcpdump抓包的方法: 1,运行下面命令来从所有网卡中捕获数据包: tcpdump -i any 2,从指定网卡中捕获数据包 tcpdump -i eth0 …

    Linux 2023年6月14日
    0142
  • 记录XorDDos木马清理步骤

    1.检查 查看定时任务文件发现有两个异常定时任务 [root@manage ~]# cat /etc/crontab user-name command to be execute…

    Linux 2023年6月7日
    0116
  • 网络设备配置–6、通过RIP协议配置动态路由

    一、前言 同系列前几篇:网络设备配置–1、配置交换机enable、console、telnet密码网络设备配置–2、通过交换机划分vlan网络设备配置&#8…

    Linux 2023年6月8日
    0120
  • shell 下载aliplayer 的视频

    #!/bin/bash url="http://v.example.com/8dedaec32ca9415eaa8ccd423ee33bf3/" #下载视频索引…

    Linux 2023年5月28日
    0115
  • 每天一个 HTTP 状态码 206

    206 Partial Content 是当客户端请求时使用了Range头部,服务器端回复… 206 Partial Content 206 Partial Conte…

    Linux 2023年6月7日
    0131
  • Python中使用%s占位符生成sql与literal转义防止sql注入攻击原理浅析

    问题背景 在后端服务中经常需要通过传入参数动态生成sql查询mysql,如查询用户信息、资产信息等,一条常见的sql如下: SELECT vip, coin FROM user_a…

    Linux 2023年6月6日
    0159
  • Redis学习手册(Sorted-Sets数据类型)

    一、概述: Sorted-Sets和Sets类型极为相似,它们都是字符串的集合,都不允许重复的成员出现在一个Set中。它们之间的主要差别是Sorted-Sets中的每一个成员都会有…

    Linux 2023年5月28日
    098
  • nginx配置文件单独创建和管理

    在nginx主配置文件nginx.conf的http模块下引入配置文件夹(注意路径的正确性) 1、nginx主配置文件备份后编辑(nginx配置存放位置:/usr/local/ng…

    Linux 2023年6月6日
    0105
  • 回顾乐信集团工作经历

    2019年入职乐信用户增长部门,负责开发开放平台的需求和合作方技术支持。乐信金融开放平台提供了金融业务API以及配套SDK等组件,为合作商户的产品赋予分期支付和小额贷款能力,子系统…

    Linux 2023年6月6日
    0108
  • 无线配置多一个路由器作为家庭wifi的无线热点?

    以下内容为本人的著作,如需要转载,请声明原文链接微信公众号「englyf」 https://mp.weixin.qq.com/s/8OcDnY3O6ux41GntesHHcg 手头…

    Linux 2023年6月6日
    0125
  • Linux 搭建Apollo

    简介 Apollo(阿波罗)是携程框架部门研发的分布式配置中心,能够集中化管理应用不同环境、不同集群的配置,配置修改后能够实时推送到应用端,并且具备规范的权限、流程治理等特性,适用…

    Linux 2023年6月14日
    0138
  • 基础算法题

    Problem 3或5的倍数 2: 偶斐波那契数 4:最大回文乘积 5 窗口移动 11:方向数组 13大整数加法 、 14最长考拉兹序列 15:网格路径 25:1000位斐波那契数…

    Linux 2023年6月7日
    0162
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球