MySQL高可用集群搭建 ----- MHA

浅浅的花香味﹌ 2024-04-19 08:03 164阅读 0赞

一、何为高可用?

高可用性说白了就是应用可以 持续不间断提供服务的能力!

注:
高可用和负载均衡的概念有些初学者可能会混淆,在这也说说负载均衡:

负载均衡:指后端服务器没有状态,可以任意分配,它们之间是同时工作的,能够通过增加机器增加吞吐量、减小服务器压力

高可用:指后端服务器有状态,一般来说是一主一备的结构,它们之间是一个工作另一个不工作在主服务器出故障后,备服务器去接管服务,从而达到持续不间断的提供服务。

二、MHA介绍

MHA使用perl语言编写的一个脚本管理管理工具,用于维持master主库的高可用性。
MHA包含两个部分:MHA Manager(管理节点)和MHA Node(数据节点)
在这里插入图片描述
MHA原理:

MHA用于维持 MySQL Replication 中 master 库的高可用性,最大的特点是可以修复多个slave上的差异日志,最终使所有slave保持数据一致,然后从中选取一个充当新的 master,并让其他 slave 指向它。

当master出现故障时,通过对比 slave 之间的 I/O thread 读取主库的 binlog 的 position 号,选取最接近的slave作为备胎(被选主库),其它从库通过与备胎对比,生成差异的中继日志,在备胎上运用从原来的 master 保存的 binlig,同时将备胎提升为master。最后在其他 slave 上运用相应的差异中继日志,并从新的 master 开始复制。

优点:

  • 故障切换时,自动判断哪个从库与主库离的最近,并切换到上面
  • 支持binlog server,提高 binlog 的传送效率
  • 结合半同步功能,确保故障切换时数据不丢失

三、实验环境介绍

使用三台机器来完成本次MHA的搭建:

  1. IP 主机名 系统版本 角色 节点
  2. 172.25.5.1 lxn1 RHEL7 master node node1
  3. 172.25.5.3 lxn3 RHEL7 slave1 node node2
  4. 172.25.5.4 lxn4 RHEL7 slave2 node+manager node3

四、MHA搭建

MHA下载:

https://github.com/yoshinorim/mha4mysql-manager
https://github.com/yoshinorim/mha4mysql-node

  1. wget https://github.com/yoshinorim/mha4mysql-manager/releases/download/v0.58/mha4mysql-manager-0.58.tar.gz
  2. wget https://github.com/yoshinorim/mha4mysql-node/releases/download/v0.58/mha4mysql-node-0.58.tar.gz

1、配置三台机器免密通信

所有节点都执行生成密钥操作

  1. cd /root/.ssh/
  2. ssh-keygen -t dsa -P '' -f id_dsa
  3. cat id_dsa.pub >> authorized_keys
  • 以主库示例,所有节点都要操作
    在这里插入图片描述

在主库上接收slave上的密钥

  1. scp 172.25.5.3:/root/.ssh/authorized_keys ./authorized_keys.3
  2. scp 172.25.5.4:/root/.ssh/authorized_keys ./authorized_keys.4

在主库上执行合并密钥的命令

  1. cat authorized_keys.3 >> authorized_keys
  2. cat authorized_keys.4 >> authorized_keys

在主库上将合并后的密钥文件发给其他节点

  1. scp authorized_keys 172.25.5.3:/root/.ssh/
  2. scp authorized_keys 172.25.5.4:/root/.ssh/
  • 完整命令截图(进供参考)

在这里插入图片描述

所有节点在/etc/hosts文件中写入本地解析:

  1. 172.25.5.1 lxn1 node1
  2. 172.25.5.3 lxn3 node2
  3. 172.25.5.4 lxn4 node3

测试

能够互相ssh且不要密码,即成功!

示例:

在这里插入图片描述

2、搭建主从环境

环境说明

本次实验搭建的是一主两从环境,使用的MySQL5.7版本,基于GTID+row模式

在所有服务器MySQL上执行以下操作

  1. #创建主从复制帐号
  2. create user 'gtid'@'172.25.5.%' identified by 'gtid123';
  3. grant replication slave on *.* to 'gtid'@'172.25.5.%';
  4. flush privileges;
  5. #创建管理帐号
  6. create user 'manage'@'172.25.5.%' identified by 'manage123';
  7. grant all privileges on *.* to 'manage'@'172.25.5.%';
  8. flush privileges;

在主库上复制数据到所有从库,完成在某个时刻GTID的同步

  1. mysqldump --single-transaction -uroot -p -A > all.sql
  2. scp all.sql node2:/root/
  3. scp all.sql node3:/root/

在这里插入图片描述

在各从库上恢复备份并配置主从复制,开启主从同步

  1. mysql -uroot -p < all.sql
  2. mysql -uroot -p
  3. root@localhost [(none)]>change master to
  4. -> master_host='172.25.5.1',
  5. -> master_user='gtid',
  6. -> master_password='gtid123',
  7. -> master_auto_position=1;
  8. root@localhost [(none)]>start slave;
  9. root@localhost [(none)]>show slave status\G
  • 注:
    Slave_IO_Running: Yes
    Slave_SQL_Running: Yes
    为主从搭建成功!

在这里插入图片描述

3、安装MHA-Node节点

在所有节点上安装数据节点

首先安装 MySQL 依赖的 perl 环境

  1. yum install perl-DBD-MySQL.x86_64 -y

解压 mha4mysql-node 包,并安装 perl-cpan

  1. tar -zxf mha4mysql-node-0.58.tar.gz
  2. cd mha4mysql-node-0.58/
  3. yum install perl-CPAN* -y
  4. perl Makefile.PL
  5. make && make install

4、安装配置 MHA-Manager 管理节点

以下操作都是在node3(172.25.5.4)上完成的

安装环境需要的介质包:

  • 注意:我的操作系统是rhel7,下载软件时注意软件版本问题

    yum install perl-DBD-MySQL*

    wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/matthewdva:/build:/RedHat:/RHEL-7/complete/x86_64/perl-Params-Validate-1.08-4.el7.x86_64.rpm
    rpm -ivh perl-Params-Validate-1.08-4.el7.x86_64.rpm

    wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/csbuild:/Perl/RHEL_7/noarch/perl-Config-Tiny-2.20-1.2.noarch.rpm
    rpm -ivh perl-Config-Tiny-2.20-1.2.noarch.rpm

    wget ftp://ftp.pbone.net/mirror/ftp5.gwdg.de/pub/opensuse/repositories/home:/csbuild:/Perl/RHEL_7/noarch/perl-Log-Dispatch-2.41-2.2.noarch.rpm
    rpm -ivh perl-Log-Dispatch-2.41-2.2.noarch.rpm

    wget ftp://ftp.pbone.net/mirror/download.fedora.redhat.com/pub/fedora/epel/7/aarch64/Packages/p/perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm
    rpm -ivh perl-Parallel-ForkManager-1.18-2.el7.noarch.rpm

安装管理节点

  1. tar -zxf mha4mysql-manager-0.58.tar.gz
  2. cd mha4mysql-manager-0.58
  3. perl Makefile.PL
  4. make && make install

配置MHA

  1. mkdir /etc/mha
  2. mkdir -p /usr/local/mha
  3. cd /etc/mha/
  4. vim mha.conf
  5. #####################################################写入配置
  6. [server default]
  7. user=manage
  8. password=manage123
  9. manager_log=/usr/local/mha/manager.log
  10. manager_workdir=/usr/local/mha
  11. master_binlog_dir=/mvtech/mysql/logs
  12. remote_workdir=/usr/local/mha
  13. ssh_user=root
  14. repl_user=gtid
  15. repl_password=gtid123
  16. master_ip_failover_script=/usr/local/scripts/master_ip_failover
  17. master_ip_online_change_script=/usr/local/scripts/master_ip_online_change
  18. ping_interval=1
  19. [server1]
  20. hostname=172.25.5.1
  21. ssh_port=22
  22. master_binlog_dir=/data/mysql
  23. candidate_master=1
  24. port=3306
  25. [server2]
  26. candidate_master=1
  27. hostname=172.25.5.3
  28. ssh_port=22
  29. master_binlog_dir=/data/mysql
  30. port=3306
  31. [server3]
  32. hostname=172.25.5.4
  33. ssh_port=22
  34. master_binlog_dir=/data/mysql
  35. no_master=1
  36. port=3306
  37. ####################################################

编辑 failover 切换脚本

  1. mkdir /usr/local/mha/scripts
  2. cd /usr/local/mha/scripts
  3. vim master_ip_failover
  4. #脚本内部的VIP和网卡需要根据自己的实际要求更改
  5. ###############################################写入
  6. #!/usr/bin/env perl
  7. use strict;
  8. use warnings FATAL =>'all';
  9. use Getopt::Long;
  10. my (
  11. $command, $ssh_user, $orig_master_host, $orig_master_ip,
  12. $orig_master_port, $new_master_host, $new_master_ip, $new_master_port
  13. );
  14. my $vip = '172.25.5.100/24'; # Virtual IP 这里需要根据自己的环境修改
  15. my $key = "1";
  16. my $ssh_start_vip = "/sbin/ifconfig ens39:$key $vip"; #注意网卡
  17. my $ssh_stop_vip = "/sbin/ifconfig ens39:$key down";
  18. my $exit_code = 0;
  19. GetOptions(
  20. 'command=s' => \$command,
  21. 'ssh_user=s' => \$ssh_user,
  22. 'orig_master_host=s' => \$orig_master_host,
  23. 'orig_master_ip=s' => \$orig_master_ip,
  24. 'orig_master_port=i' => \$orig_master_port,
  25. 'new_master_host=s' => \$new_master_host,
  26. 'new_master_ip=s' => \$new_master_ip,
  27. 'new_master_port=i' => \$new_master_port,
  28. );
  29. exit &main();
  30. sub main {
  31. #print "\n\nIN SCRIPT TEST====$ssh_stop_vip==$ssh_start_vip===\n\n";
  32. if ( $command eq "stop" || $command eq "stopssh" ) {
  33. # $orig_master_host, $orig_master_ip, $orig_master_port are passed.
  34. # If you manage master ip address at global catalog database,
  35. # invalidate orig_master_ip here.
  36. my $exit_code = 1;
  37. eval {
  38. print "\n\n\n***************************************************************\n";
  39. print "Disabling the VIP - $vip on old master: $orig_master_host\n";
  40. print "***************************************************************\n\n\n\n";
  41. &stop_vip();
  42. $exit_code = 0;
  43. };
  44. if ($@) {
  45. warn "Got Error: $@\n";
  46. exit $exit_code;
  47. }
  48. exit $exit_code;
  49. }
  50. elsif ( $command eq "start" ) {
  51. # all arguments are passed.
  52. # If you manage master ip address at global catalog database,
  53. # activate new_master_ip here.
  54. # You can also grant write access (create user, set read_only=0, etc) here.
  55. my $exit_code = 10;
  56. eval {
  57. print "\n\n\n***************************************************************\n";
  58. print "Enabling the VIP - $vip on new master: $new_master_host \n";
  59. print "***************************************************************\n\n\n\n";
  60. &start_vip();
  61. $exit_code = 0;
  62. };
  63. if ($@) {
  64. warn $@;
  65. exit $exit_code;
  66. }
  67. exit $exit_code;
  68. }
  69. elsif ( $command eq "status" ) {
  70. print "Checking the Status of the script.. OK \n";
  71. `ssh $ssh_user\@$orig_master_host \" $ssh_start_vip \"`;
  72. exit 0;
  73. }
  74. else {
  75. &usage();
  76. exit 1;
  77. }
  78. }
  79. # A simple system call that enable the VIP on the new master
  80. sub start_vip() {
  81. `ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`;
  82. }
  83. # A simple system call that disable the VIP on the old_master
  84. sub stop_vip() {
  85. `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`;
  86. }
  87. sub usage {
  88. print
  89. "Usage: master_ip_failover –command=start|stop|stopssh|status –orig_master_host=host –orig_master_ip=ip –orig_master_port=po
  90. rt –new_master_host=host –new_master_ip=ip –new_master_port=port\n";
  91. }
  92. ###############################################
  93. chmod +x master_ip_failover

编写 online_change 脚本

  1. vim master_ip_online_change
  2. #注意VIP
  3. ###############################################写入
  4. #/bin/bash
  5. source /root/.bash_profile
  6. vip=`echo '172.25.5.100/24'` # Virtual IP
  7. key=`echo '1'`
  8. command=`echo "$1" | awk -F = '{print $2}'`
  9. orig_master_host=`echo "$2" | awk -F = '{print $2}'`
  10. new_master_host=`echo "$7" | awk -F = '{print $2}'`
  11. orig_master_ssh_user=`echo "${12}" | awk -F = '{print $2}'`
  12. new_master_ssh_user=`echo "${13}" | awk -F = '{print $2}'`
  13. stop_vip=`echo "ssh root@$orig_master_host /sbin/ifconfig eth0:$key down"`
  14. start_vip=`echo "ssh root@$new_master_host /sbin/ifconfig eth0:$key $vip"`
  15. if [ $command = 'stop' ]
  16. then
  17. echo -e "\n\n\n***************************************************************\n"
  18. echo -e "Disabling the VIP - $vip on old master: $orig_master_host\n"
  19. $stop_vip
  20. if [ $? -eq 0 ]
  21. then
  22. echo "Disabled the VIP successfully"
  23. else
  24. echo "Disabled the VIP failed"
  25. fi
  26. echo -e "***************************************************************\n\n\n\n"
  27. fi
  28. if [ $command = 'start' -o $command = 'status' ]
  29. then
  30. echo -e "\n\n\n***************************************************************\n"
  31. echo -e "Enabling the VIP - $vip on new master: $new_master_host \n"
  32. $start_vip
  33. if [ $? -eq 0 ]
  34. then
  35. echo "Enabled the VIP successfully"
  36. else
  37. echo "Enabled the VIP failed"
  38. fi
  39. echo -e "***************************************************************\n\n\n\n"
  40. fi
  41. #############################################
  42. chmod +x master_ip_online_change

检测所有主机的连通性:

  1. /usr/local/bin/masterha_check_ssh --conf=/etc/mha/mha.conf

在这里插入图片描述
检测复制状态:

  1. /usr/local/bin/masterha_check_repl --conf=/etc/mha/mha.conf

在这里插入图片描述

  • 注:这里容易报错,请仔细看报错,能解决

5、在主库上添加VIP

  1. ip addr add 172.25.5.100/24 dev ens39

在这里插入图片描述

6、在管理节点启动MHA服务

启动MHA:

  1. nohup masterha_manager --conf=/etc/mha/mha.conf > /tmp/mha_manager.log < /dev/null 2>&1 &

检测MHA是否启动:

  1. masterha_check_status --conf=/etc/mha/mha.conf

在这里插入图片描述

五、模拟主库故障,故障切换

0、模拟主库(172.25.5.1)故障

kill 掉主库MySQL服务

在这里插入图片描述

1、MHA 自动切换主库

VIP 漂移
在这里插入图片描述

在node2(172.25.5.3)上:

VIP 漂移
在这里插入图片描述

在node3(172.25.5.4)上看主从信息:

  • master切换到了node2(172.25.5.3),高可用成功!
    在这里插入图片描述
    切换 master 后,MHA进程会自动关闭 ,并生成文件 mha.failover.complete

    masterha_check_status —conf=/etc/mha/mha.conf

在这里插入图片描述

  • mha.failover.complete 文件:该文件生成后,将不在允许主库故障后自动切换

2、手动切换主库

手动failover,这种场景意味着在业务上没有启用MHA自动切换功能,当主服务器故障时,人工手动调用MHA来进行故障切换操作

环境介绍

由于刚才 MHA 自动切换成功,所以现在主库是172.25.5.3,重启宕掉的主库后成为新的slave

在这里插入图片描述
为了确保不会自动切换,停掉 MHA 进程:

  1. masterha_stop --conf=/etc/mha/mha.conf

在这里插入图片描述
将主库kill掉
在这里插入图片描述

主库切换失败:
在这里插入图片描述

MHA 自动切换主库失败后,可以用手动切换

在管理节点操作:

  1. masterha_master_switch --master_state=dead --conf=/etc/mha/mha.conf --dead_master_host=172.25.5.3 --dead_master_port=3306 --new_master_ip=172.25.5.1 --new_master_port=3306

在这里插入图片描述
切换成功:
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

将宕掉的MySQL主库恢复起来

node1,原主库

  1. mysqld_safe --defaults-file=/etc/my.cnf &

重新指向新的主库,配置主从

node1,原主库

  1. mysql -uroot -p
  2. root@localhost [(none)]>change master to
  3. -> master_host='172.25.5.3',
  4. -> master_user='gtid',
  5. -> master_password='gtid123',
  6. -> master_auto_position=1;
  7. root@localhost [(none)]>start slave;
  8. root@localhost [(none)]>show slave status\G
  • 至此,新的一主两从结构完成!

在这里插入图片描述
在这里插入图片描述

六、让宕掉的主库重新成为新的主库

  • 手动回切需要关闭MHA监控,如下图
  • masterha_check_status —conf=/etc/mha/mha.conf 来查看MHA监控是否打开

在这里插入图片描述
将宕掉的MySQL主库重启并成为新的 slave 后,在管理节点操作

  1. masterha_master_switch --conf=/etc/mha/mha.conf --master_state=alive --new_master_host=172.25.5.1 --orig_master_is_new_slave

在这里插入图片描述
在node2节点(刚才故障切换的新主库)上可以看到:node2已经成为了一个slave,而主库是172.25.5.1(node1)
在这里插入图片描述

发表评论

表情:
评论列表 (有 0 条评论,164人围观)

还没有评论,来说两句吧...

相关阅读