热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

MySQLforOPS08:MHA高可用

写在前面的话

 

主从架构在一般情况下只能满足我们小公司业务并非一刻都不能中断服务。但是对于大型公司而言,对然数据丢失,数据库挂了,我们可以通过技术找回,修复。但是其中修复过程所消耗的时间是不被允许的。此时就需要引入高可用,以保证我们主库在宕机情况下有另外的数据库顶上去,以保证我们的服务 7 x 24 无间断。

 

 

数据库基本架构

 

在日常的小项目中,对于数据库的基本架构一般有以下选型:

1. 一主一从 /  一主多从

2. 多级主从

3. 双主

4. 循环复制

 

高级一点的高性能架构,也就是需要第三方服务帮助的架构:

1. 读写分离。常见的基于 MySQL Proxy 的有:Atlas / MySQL Router / ProxySQL / MaxScale 等

2. 分布式架构。常见的有:Cobar / TDDL / Mycat 等

 

最后就是高可用架构:

1. 单活 MMM,谷歌的 mysql-mmm。

2. 单活 MHA,日本人开发的 mysql-master-ha。

3. 多活 MGR,MySQL 5.7.17 以后官方新特性,基于组的复制。

4. 其它的 MariaDB,Percona 自己的 Cluster 架构。

 

 

MHA 环境搭建

 

对于 MHA,可以类比为 Zabbix,拥有 Server 端和 Agent 端,这里就是 Manager 和 Node 端。

整个架构至少包含 3 个数据库,其结构为一主两从,所以这里我们准备了 4 个服务器:

MySQL for OPS 08:MHA 高可用

 

1. 三台服务器都安装 MySQL 数据库并配置好一主两从,具体步骤就不再赘述。

2. 四台服务器都配置 SSH 互信(SSH 免密登录):

# MHA Master 上面生成密钥
rm -rf /root/.ssh 
ssh-keygen 
cd /root/.ssh
mv id_rsa.pub authorized_keys

# 发送密钥到其它主机
scp  -r  /root/.ssh root@192.168.100.111:/root
scp  -r  /root/.ssh root@192.168.100.112:/root
scp  -r  /root/.ssh root@192.168.100.113:/root

# 所有服务器上面测试连接,注意每台都单独执行一次,第一次会有个 yes 确认
ssh root@192.168.100.101 date
ssh root@192.168.100.111 date
ssh root@192.168.100.112 date
ssh root@192.168.100.113 date

 

3. 下载 MHA:

https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads

只能下载 RHEL 6 的:

MySQL for OPS 08:MHA 高可用

 

4. 在所有 MySQL 节点安装 Node:

# 安装依赖
yum install -y perl-Config-Tiny epel-release perl-Log-Dispatch perl-Parallel-ForkManager perl-Time-HiRes

# 安装 Node
rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

# MHA manager 节点还要按照 manager
rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

 

5. 在主库中创建用于 mha 管理的用户:

grant all on *.* to 'mha'@'192.168.100.%' identified by '123';

 

6. 在 Manager 节点添加配置文件,由于一个 Manager 是可以管理多个 node 集群的,所以最好进行项目区分:

# Manager 节点创建配置和日志目录,这里以 test 项目为例
mkdir -p /etc/mha/test/{conf,logs,data,bin}

# 添加配置
vim /etc/mha/test/conf/test.conf

配置详情如下:

[server default]
manager_log=/etc/mha/test/logs/manager.log
manager_workdir=/etc/mha/test/data
master_binlog_dir=/data/logs/mysql/binlog
user=mha
password=123
ping_interval=2
repl_user=repl
repl_password=123
ssh_user=root

[server1]
hostname=192.168.100.111
port=3306
[server2]
hostname=192.168.100.112
port=3306
[server3]
hostname=192.168.100.113
port=3306

其中包含 manager 日志路径,工作路径,MySQL binlog 路径,mha 用户,同步用户,ssh 远程用户,以及各个节点。

ping_interval=2 的意思是,每个两秒检测一次,一共检查 3 次,如果三次全失败才算失败。

 

7. manager 节点测试 SSH 连通性和主从状态:

masterha_check_ssh  --cOnf=/etc/mha/test/conf/test.conf

结果如图:

MySQL for OPS 08:MHA 高可用

所有节点 SSH 都是通的。

masterha_check_repl --cOnf=/etc/mha/test/conf/test.conf

结果如图:

MySQL for OPS 08:MHA 高可用

如果有节点是挂的或者不通,则会报异常。

 

8. 补充说明 MHA 工具包:

命令 用途
masterha_manager 启动 MHA 命令
masterha_check_ssh SSH 连接检测命令
masterha_check_repl 主从状态检测命令
masterha_master_monitor 检测 Master 是否宕机
masterha_check_status 检测当前 MHA 运行状态
masterha_conf_host 添加或删除 server 配置
masterha_stop 停止 MHA

 

9. manager 节点启动 MHA:

nohup masterha_manager --cOnf=/etc/mha/test/conf/test.conf --remove_dead_master_conf --ignore_last_failover   /etc/mha/test/logs/manager.log 2>&1 &

查看状态:

masterha_check_status --cOnf=/etc/mha/test/conf/test.conf

结果如图:

MySQL for OPS 08:MHA 高可用

显示 MHA 正在运行,且 111 为主库。到此,简单的 MHA 高可用架构就搭建完成。

 

 

MHA 架构工作原理

 

1. 监控原理:

MHA manager 节点通过服务提供的 perl 脚本对主从环境的节点信息,网络,系统,SSH 连通性,主从状态进行监控。

所以需要配置互信,否则监控的时候服务器无法连接过去。

 

2. 当 Master 节点宕机后,从新选主的规则:

a. 如果 master 和 slave 之间存在延时,则指针或 GTID 最接近主库的成为备选主。

b. 如果两个 slave 的指针或 GTID 相同,则 MHA 配置文件中谁在前面谁成为备选主。

c. 如果配置了权重(candiate_master=1),则按照权重选取:

特殊情况:当 slave 的 relay log 落后主 100M 则权重也不会选他。如果配置了 check_repl_delay=0,则无论如何都选他。

 

3. 数据补偿机制:

在主库宕机时,并非所以的数据都可能同步完成:

a. SSH 还能连接主库,则立即同步主库 binlog 并应用到新主中(也就是 Node 的 save_binary_logs 脚本,系统自动调用)。

b. SSH 不能连接主库,则对比从库之间的 relaylog(也就是 Node 的 apply_diff_relay_logs 脚本的功能)。

 

4. Failover:

将备选主身份切换,继续对外提供服务,其余从库和新主从新建立主从关系。

 

5. 剩下的 VIP / 故障切换通知 / 二次数据补偿后面再说。

 

 

模拟主库宕机示例

 

1. 停止主库,模拟主库宕机:

systemctl stop mysqld

此时查看 MHA manager 状态:

MySQL for OPS 08:MHA 高可用

Manager 进程退出,查看状态:

masterha_check_status --cOnf=/etc/mha/test/conf/test.conf

如图:

MySQL for OPS 08:MHA 高可用

查看 MHA 配置文件:

MySQL for OPS 08:MHA 高可用

发现宕机的主机配置已经被自动删除掉了。

 

2. 查看新的主从关系:

MySQL for OPS 08:MHA 高可用

登录从库 2 看到主库以及变更成为之前的从库 1 了。

 

3. 此时如果之前的主库恢复了,如何加入 MHA 集群中去:

简单,由于是 GTID 复制,我们都不需要从新导入数据,直接 change master 到新的主库即可。

这是主从得知识点,这里就不再说明。

MySQL for OPS 08:MHA 高可用

 

4. 添加之前被 MHA 删掉的 server 配置:

[server1]
hostname=192.168.100.111
port=3306

 

5. 再度启动 MHA:

nohup masterha_manager --cOnf=/etc/mha/test/conf/test.conf --remove_dead_master_conf --ignore_last_failover   /etc/mha/test/logs/manager.log 2>&1 &

查看 MHA 状态:

masterha_check_status --cOnf=/etc/mha/test/conf/test.conf

如图:

MySQL for OPS 08:MHA 高可用

到此,简单的故障切换完成!

 

 

MHA 的 VIP

 

有过运维经验的人此时就发现问题了,而且是大问题。虽然你主从切换了,但是我们业务的服务配置的数据库 IP 地址宕机的那台数据库的。所以我服务还是挂了。这好像并没有解决我们的问题。

于是突发奇想,当初在使用 LVS 或者 Nginx 搭配 Keepalived 使用的时候,有了 VIP(虚拟网卡 IP)的概念,要是能在这使用就好了。

在早期的 MHA 中确实是使用 Keepalived,后来 MHA 自己加入了 VIP 功能,其实就是加入了脚本执行功能,让我们能自己想办法实现。

 

1. 这里会用到一个脚本,是 perl 语言写的: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
);
 
# VIP 地址
my $vip = '192.168.100.120/24';
# 虚拟网卡后缀编号
my $key = "1";
# 虚拟网卡使用的网卡
my $ssh_start_vip = "/sbin/ifconfig ens33:$key $vip";
my $ssh_stop_vip = "/sbin/ifconfig ens33:$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" ) {
 
        # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
        # If you manage master ip address at global catalog database,
        # invalidate orig_master_ip here.
        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" ) {
 
        # all arguments are passed.
        # If you manage master ip address at global catalog database,
        # activate new_master_ip here.
        # You can also grant write access (create user, set read_Only=0, etc) here.
        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"; 
        `ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
        exit 0;
    }
    else {
        &usage();
        exit 1;
    }
}
 
# A simple system call that enable the VIP on the new master 
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";
}

这里主要注意红色部分!其脚本原理就是使用 ifconfig 给网卡配置 IP 地址。

我这里网卡是 ens33,所以配置虚拟 IP 在 ens33:1 上面。

把 master_ip_failover 脚本上传到 Manager 节点的 /etc/mha/test/bin 下面。

cd /etc/mha/test/bin
dos2unix master_ip_failover 
chmod 755 master_ip_failover

 

2. 事先给主库配置好虚拟 IP:

ifconfig ens33:1 192.168.100.120/24

查看:

MySQL for OPS 08:MHA 高可用

 

3. 在 MHA 配置文件中加入脚本路径:

master_ip_failover_script=/etc/mha/test/bin/master_ip_failover

 

4. 重启 MHA:

# 停止 MHA
masterha_stop --cOnf=/etc/mha/test/conf/test.conf

# 启动 MHA
nohup masterha_manager --cOnf=/etc/mha/test/conf/test.conf --remove_dead_master_conf --ignore_last_failover   /etc/mha/test/logs/manager.log 2>&1 &

至此,VIP 配置完成!

 

 

VIP 故障恢复示例

 

此时我同样停止主库,模拟故障发生:

systemctl stop mysqld

同时 MHA 会自动退出:

MySQL for OPS 08:MHA 高可用

查看当前主从关系:

MySQL for OPS 08:MHA 高可用

发现主库重新回到了 111 上面。

MySQL for OPS 08:MHA 高可用

同时 VIP 也漂移到了 111 上面!至此,故障 VIP 切换完成。当然,故障恢复和之前一样:

1. 重新建立主从关系。

2. 给 MHA 配置文件加上被删除的配置。

3. 启动 MHA 服务。

 

 

故障告警通知

 

我们在故障发生时,由于自动切换,我们可能并不知道主库已经宕机了,当然特别去关注除外。为了更好的知道线上的服务情况,我们可能会使用一系列的监控手段。比如 Zabbix 这类。

其实 MHA 是能够让我们发生告警消息的,但其实原理和 VIP 切换一样,都是使用执行脚本的方式。

1. 这里以钉钉机器人发消息为例:

#!/bin/bash 

DB_ADDRESS=$(cat /etc/mha/test/logs/manager.log | grep 'Master failover' | tail -1 | cut -d'(' -f2 | cut -d')' -f1)

function SendMessageToDingding(){ 
    Dingding_Url="https://oapi.dingtalk.com/xxxxxxx 这是你自己的钉钉机器人 Token" 
    # 发送钉钉消息
    curl "${Dingding_Url}" -H 'Content-Type: application/json' -d "
    {
        \"actionCard\": {
            \"title\": \"$1\", 
            \"text\": \"$2\", 
            \"hideAvatar\": \"0\", 
            \"btnOrientation\": \"0\", 
            \"btns\": [
                {
                    \"title\": \"$1\", 
                    \"actionURL\": \"\"
                }
            ]
        }, 
        \"msgtype\": \"actionCard\"
    }"
} 

Subject="数据库主库宕机啦~" 

Body="新主库:${DB_ADDRESS}"

SendMessageToDingding $Subject $Body

至于这个脚本写法,可以参照我之前的博客:

https://www.cnblogs.com/Dy1an/p/9264691.html

将脚本上传到 /etc/mha/test/bin 下面,我给它命名:send_dingding_message,注意修改它的权限。

 

2. 在配置文件中加入 report_send:

report_script=/etc/mha/test/bin/send_dingding_message

重启 MHA,然后停止主库模拟故障,这样就能收到钉钉通知了:

MySQL for OPS 08:MHA 高可用

 

当然你也可以以其它方式通知,比如邮件。脚本都很简单。

 

 

binlog 远程保存

 

很多时候主库宕机可能出现一个问题,binlog 未及时同步或者本身设置了延时同步。此时如果主库机器已经坏了,这意味着数据就挂了。

那就得想一个办法,类似于将它的 binlog 保留一份到其他机器专门用于出现这样得情况时候从数据库好去这上面查看 binlog 从而实现二次数据补偿。

这就是这个小节需要实现得东西。我们将 binlog 备份保留到 manager 上面。

1. 由于需要用到 MySQL 命令,所以安装 MySQL,并不需要启动,安装方法参考前面得博客:

MySQL for OPS 08:MHA 高可用

 

2. 在 MHA 配置文件中加入 binlog 备份配置:

[binlog1]
no_master=1
hostname=192.168.100.101
master_binlog_dir=/data/backup/mysql/binlog

并创建该目录授权:

mkdir /data/backup/mysql/binlog
chown -R mysql.mysql /data/backup/mysql

 

3. 查看当前从库的 binlog 文件名:

show slave status\G

结果:

MySQL for OPS 08:MHA 高可用

 

4. 去 manager 节点拉去该日志:

cd /data/backup/mysql/binlog/
mysqlbinlog -R --host=192.168.100.111 --user=mha --password=123 --raw --stop-never mysql-bin.000003 &

这比如进入目录。

 

5. 重启 MHA:

masterha_stop --cOnf=/etc/mha/test/conf/test.conf
nohup masterha_manager --cOnf=/etc/mha/test/conf/test.conf --remove_dead_master_conf --ignore_last_failover   /etc/mha/test/logs/manager.log 2>&1 &

可以 ps 查看到两个进程:

MySQL for OPS 08:MHA 高可用

 

6. 去主库刷新日志查看:

MySQL for OPS 08:MHA 高可用

查看备份:

MySQL for OPS 08:MHA 高可用

自动已经开始备份新的 binlog 文件。至此异地备份完成,主库宕机,从库会自动读取这里最终实现数据一致。

 

恢复说明:

这个恢复有点不一样,当从库从 binlog 恢复完成以后。

1. 重新将故障主机加入主从。

2. 清空 binlog 备份,在 MHA 中重新加入 binlog 配置和 server 配置。

3. 重新启动 MHA 架构恢复。

 

 

小结

 

高可用肯定是数据库的一个核心功能,本文的 MHA 主要从高可用 + VIP + 发送告警 + binlog 备份恢复来完善高可用。最好的搭建时候其实就是感慨是设计架构的时候。当然,高可用的架构阿里云也是有的,阿里云的 RDS 就自带高可用。


推荐阅读
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文详细介绍了SQL日志收缩的方法,包括截断日志和删除不需要的旧日志记录。通过备份日志和使用DBCC SHRINKFILE命令可以实现日志的收缩。同时,还介绍了截断日志的原理和注意事项,包括不能截断事务日志的活动部分和MinLSN的确定方法。通过本文的方法,可以有效减小逻辑日志的大小,提高数据库的性能。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 本文介绍了如何使用php限制数据库插入的条数并显示每次插入数据库之间的数据数目,以及避免重复提交的方法。同时还介绍了如何限制某一个数据库用户的并发连接数,以及设置数据库的连接数和连接超时时间的方法。最后提供了一些关于浏览器在线用户数和数据库连接数量比例的参考值。 ... [详细]
  • 本文由编程笔记小编整理,介绍了PHP中的MySQL函数库及其常用函数,包括mysql_connect、mysql_error、mysql_select_db、mysql_query、mysql_affected_row、mysql_close等。希望对读者有一定的参考价值。 ... [详细]
  • 高质量SQL书写的30条建议
    本文提供了30条关于优化SQL的建议,包括避免使用select *,使用具体字段,以及使用limit 1等。这些建议是基于实际开发经验总结出来的,旨在帮助读者优化SQL查询。 ... [详细]
  • PHP组合工具以及开发所需的工具
    本文介绍了PHP开发中常用的组合工具和开发所需的工具。对于数据分析软件,包括Excel、hihidata、SPSS、SAS、MARLAB、Eview以及各种BI与报表工具等。同时还介绍了PHP开发所需的PHP MySQL Apache集成环境,包括推荐的AppServ等版本。 ... [详细]
  • 云原生应用最佳开发实践之十二原则(12factor)
    目录简介一、基准代码二、依赖三、配置四、后端配置五、构建、发布、运行六、进程七、端口绑定八、并发九、易处理十、开发与线上环境等价十一、日志十二、进程管理当 ... [详细]
  • MySQL5.6.40在CentOS764下安装过程 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文详细介绍了MysqlDump和mysqldump进行全库备份的相关知识,包括备份命令的使用方法、my.cnf配置文件的设置、binlog日志的位置指定、增量恢复的方式以及适用于innodb引擎和myisam引擎的备份方法。对于需要进行数据库备份的用户来说,本文提供了一些有价值的参考内容。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • Oracle分析函数first_value()和last_value()的用法及原理
    本文介绍了Oracle分析函数first_value()和last_value()的用法和原理,以及在查询销售记录日期和部门中的应用。通过示例和解释,详细说明了first_value()和last_value()的功能和不同之处。同时,对于last_value()的结果出现不一样的情况进行了解释,并提供了理解last_value()默认统计范围的方法。该文对于使用Oracle分析函数的开发人员和数据库管理员具有参考价值。 ... [详细]
author-avatar
可惜偏偏孤独一个小姐_448
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有