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


推荐阅读
  • Presto:高效即席查询引擎的深度解析与应用
    本文深入解析了Presto这一高效的即席查询引擎,详细探讨了其架构设计及其优缺点。Presto通过内存到内存的数据处理方式,显著提升了查询性能,相比传统的MapReduce查询,不仅减少了数据传输的延迟,还提高了查询的准确性和效率。然而,Presto在大规模数据处理和容错机制方面仍存在一定的局限性。本文还介绍了Presto在实际应用中的多种场景,展示了其在大数据分析领域的强大潜力。 ... [详细]
  • 在开发过程中,我最初也依赖于功能全面但操作繁琐的集成开发环境(IDE),如Borland Delphi 和 Microsoft Visual Studio。然而,随着对高效开发的追求,我逐渐转向了更加轻量级和灵活的工具组合。通过 CLIfe,我构建了一个高度定制化的开发环境,不仅提高了代码编写效率,还简化了项目管理流程。这一配置结合了多种强大的命令行工具和插件,使我在日常开发中能够更加得心应手。 ... [详细]
  • 提升 Kubernetes 集群管理效率的七大专业工具
    Kubernetes 在云原生环境中的应用日益广泛,然而集群管理的复杂性也随之增加。为了提高管理效率,本文推荐了七款专业工具,这些工具不仅能够简化日常操作,还能提升系统的稳定性和安全性。从自动化部署到监控和故障排查,这些工具覆盖了集群管理的各个方面,帮助管理员更好地应对挑战。 ... [详细]
  • 小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限
    小王详解:内部网络中最易理解的NAT原理剖析,挑战你的认知极限 ... [详细]
  • MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案
    MySQL 8.0 MGR 自动化部署与配置:DBA 和开源工具的高效解决方案 ... [详细]
  • MySQL数据库安装图文教程
    本文详细介绍了MySQL数据库的安装步骤。首先,用户需要打开已下载的MySQL安装文件,例如 `mysql-5.5.40-win32.msi`,并双击运行。接下来,在安装向导中选择安装类型,通常推荐选择“典型”安装选项,以确保大多数常用功能都能被正确安装。此外,文章还提供了详细的图文说明,帮助用户顺利完成整个安装过程,确保数据库系统能够稳定运行。 ... [详细]
  • 推荐:利用Dapper.SimpleCRUD扩展Dapper功能以简化CRUD操作
    Dapper作为广受欢迎的ORM框架之一,虽然灵活性极高,但在处理基本的CRUD操作时仍需手动编写SQL语句,这无疑增加了开发工作量。为了解决这一问题,Dapper.SimpleCRUD扩展库应运而生。该扩展库通过提供简洁的方法,显著简化了数据访问层的开发流程,使开发者能够更加高效地进行读取、插入、更新和删除操作。此外,Dapper.SimpleCRUD还支持事务管理和批量操作,进一步提升了开发效率和代码可维护性。 ... [详细]
  • 在GitHub上克隆vue-element-admin项目时遇到依赖安装错误
    在 GitHub 上克隆 vue-element-admin 项目后,使用 `npm install` 安装依赖时遇到了未知的 Git 错误。具体错误信息为 `npm ERR! code 128`,提示命令执行失败。这可能是由于网络问题、Git 配置不正确或某些依赖包的仓库地址无效导致的。建议检查网络连接、更新 Git 版本并确保所有依赖项的 URL 正确无误。 ... [详细]
  • 本文详细探讨了在ASP.NET环境中通过加密数据库连接字符串来提升数据安全性的方法。加密技术不仅能够有效防止敏感信息泄露,还能增强应用程序的整体安全性。文中介绍了多种加密手段及其实施步骤,帮助开发者在日常开发过程中更好地保护数据库连接信息,确保数据传输的安全可靠。 ... [详细]
  • 如何高效地安装并配置 PostgreSQL 数据库系统?本文将详细介绍从下载到安装、配置环境变量、初始化数据库、以及优化性能的全过程,帮助读者快速掌握 PostgreSQL 的核心操作与最佳实践。文章还涵盖了常见问题的解决方案,确保用户在部署过程中能够顺利解决遇到的各种挑战。 ... [详细]
  • 在使用 SQL Server 时,连接故障是用户最常见的问题之一。通常,连接 SQL Server 的方法有两种:一种是通过 SQL Server 自带的客户端工具,例如 SQL Server Management Studio;另一种是通过第三方应用程序或开发工具进行连接。本文将详细分析导致连接故障的常见原因,并提供相应的解决策略,帮助用户有效排除连接问题。 ... [详细]
  • SSAS入门指南:基础知识与核心概念解析
    ### SSAS入门指南:基础知识与核心概念解析Analysis Services 是一种专为决策支持和商业智能(BI)解决方案设计的数据引擎。该引擎能够为报告和客户端应用提供高效的分析数据,并支持在多维数据模型中构建高性能的分析应用。通过其强大的数据处理能力和灵活的数据建模功能,Analysis Services 成为了现代 BI 系统的重要组成部分。 ... [详细]
  • 手指触控|Android电容屏幕驱动调试指南
    手指触控|Android电容屏幕驱动调试指南 ... [详细]
  • 2016-2017学年《网络安全实战》第三次作业
    2016-2017学年《网络安全实战》第三次作业总结了教材中关于网络信息收集技术的内容。本章主要探讨了网络踩点、网络扫描和网络查点三个关键步骤。其中,网络踩点旨在通过公开渠道收集目标信息,为后续的安全测试奠定基础,而不涉及实际的入侵行为。 ... [详细]
  • 1. 设置用户密码:使用 `slappasswd` 工具生成加密密码,确保账户安全。具体步骤如下:输入命令 `slappasswd -s NewPassword`,系统将提示重新输入新密码,并生成加密后的哈希值 {SSHA}xxxxxxxxxxxxxxxxx。2. 编写配置文件:编辑 `vildapus` 配置文件,添加必要的用户账户信息,以确保新用户能够顺利登录系统。 ... [详细]
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社区 版权所有