热门标签 | 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 就自带高可用。


推荐阅读
  • 本文详细介绍了如何在ARM架构的目标设备上部署SSH服务端,包括必要的软件包下载、交叉编译过程以及最终的服务配置与测试。适合嵌入式开发人员和系统集成工程师参考。 ... [详细]
  • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
  • 本文详细介绍了如何搭建一个高可用的MongoDB集群,包括环境准备、用户配置、目录创建、MongoDB安装、配置文件设置、集群组件部署等步骤。特别关注分片、读写分离及负载均衡的实现。 ... [详细]
  • 本文详细探讨了在Web开发中常见的UTF-8编码问题及其解决方案,包括HTML页面、PHP脚本、MySQL数据库以及JavaScript和Flash应用中的乱码问题。 ... [详细]
  • 本文介绍了如何在GitHub上设置多个SSH Key,以解决原有Key失效的问题,并确保不同项目使用不同的私钥进行安全访问。 ... [详细]
  • 本文详细介绍了在 Ubuntu 系统上搭建 Hadoop 集群时遇到的 SSH 密钥认证问题及其解决方案。通过本文,读者可以了解如何在多台虚拟机之间实现无密码 SSH 登录,从而顺利启动 Hadoop 集群。 ... [详细]
  • 在Cisco IOS XR系统中,存在提供服务的服务器和使用这些服务的客户端。本文深入探讨了进程与线程状态转换机制,分析了其在系统性能优化中的关键作用,并提出了改进措施,以提高系统的响应速度和资源利用率。通过详细研究状态转换的各个环节,本文为开发人员和系统管理员提供了实用的指导,旨在提升整体系统效率和稳定性。 ... [详细]
  • Vue应用预渲染技术详解与实践 ... [详细]
  • CRZ.im:一款极简的网址缩短服务及其安装指南
    本文介绍了一款名为CRZ.im的极简网址缩短服务,该服务采用PHP和SQLite开发,体积小巧,约10KB。本文还提供了详细的安装步骤,包括环境配置、域名解析及Nginx伪静态设置。 ... [详细]
  • 调试利器SSH隧道
    在开发微信公众号或小程序的时候,由于微信平台规则的限制,部分接口需要通过线上域名才能正常访问。但我们一般都会在本地开发,因为这能快速的看到 ... [详细]
  • 从CodeIgniter中提取图像处理组件
    本指南旨在帮助开发者在未使用CodeIgniter框架的情况下,如何独立使用其强大的图像处理功能,包括图像尺寸调整、创建缩略图、裁剪、旋转及添加水印等。 ... [详细]
  • PHP面试题精选及答案解析
    本文精选了新浪PHP笔试题及最新的PHP面试题,并提供了详细的答案解析,帮助求职者更好地准备PHP相关的面试。 ... [详细]
  • 在 Ubuntu 22.04 LTS 上部署 Jira 敏捷项目管理工具
    Jira 敏捷项目管理工具专为软件开发团队设计,旨在以高效、有序的方式管理项目、问题和任务。该工具提供了灵活且可定制的工作流程,能够根据项目需求进行调整。本文将详细介绍如何在 Ubuntu 22.04 LTS 上安装和配置 Jira。 ... [详细]
  • Kafka入门指南
    本文将详细介绍如何在CentOS 7上安装和配置Kafka,包括必要的环境准备、JDK和Zookeeper的配置步骤。 ... [详细]
  • 1、形成邻居条件:1)区域ID相同;2)hello,dead时间一致;3)认证&# ... [详细]
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社区 版权所有