MHA是Master High Availability的縮寫,它是目前MySQL高可用方面的一個相對成熟的解決方案,其核心是使用perl語言編寫的一組腳本,是一套優秀的做爲MySQL高可用性環境下故障切換和主從提高的高可用軟件。在MySQL故障切換過程當中,MHA能作到在0~30秒以內自動完成數據庫的故障切換操做,而且能在最大程度上保證數據的一致性,以達到真正意義上的高可用。前端
基於MHA的架構不像MMM那樣須要搭建主主複製,只須要搭建基本的主從複製架構便可。由於MHA在主庫掛掉時,是在多個從庫中選取出一個從庫做爲新的主庫。MHA集羣中的各節點彼此之間均須要基於ssh
互信通訊,以實現遠程控制及數據管理功能。node
MHA提供了什麼功能:mysql
MHA故障轉移過程:git
ssh
登陸到宕機崩潰的Master節點上保存二進制日誌事件(binlog events);MHA的架構圖以下:github
本文中所使用的機器說明:sql
名稱 | IP | 角色 |
---|---|---|
master | 192.168.190.151 | 主庫 |
slave-01 | 192.168.190.152 | 從庫 |
slave-02 | 192.168.190.154 | 從庫 |
manager | 192.168.190.153 | 集羣管理節點(MHA) |
環境版本說明:數據庫
另外的說明:vim
一、在全部主從節點上使用以下語句建立用於主從複製的MySQL用戶,由於每一個從庫都有可能會被選舉爲主庫,因此都須要擁有用於複製的用戶:centos
create user 'repl'@'%' identified with mysql_native_password by 'Abc_123456'; grant replication slave on *.* to 'repl'@'%'; flush privileges;
二、而後修改master
節點上的MySQL配置文件:安全
[root@master ~]# vim /etc/my.cnf [mysqld] # 設置當前節點的id server_id=101 # 開啓binlog,並指定binlog文件的名稱 log_bin=mysql_bin # 開啓relay_log,並指定relay_log文件的名稱 relay_log=relay_bin # 將relaylog的同步內容記錄到binlog中 log_slave_updates=on # 開啓GTID複製模式 gtid_mode=ON enforce_gtid_consistency=1
三、在slave-01
的配置文件中也是添加同樣配置,只不過server_id
不同:
[root@slave-01 ~]# vim /etc/my.cnf [mysqld] server_id=102 log_bin=mysql_bin relay_log=relay_bin log_slave_updates=on gtid_mode=ON enforce_gtid_consistency=1
四、接着是配置slave-02
:
[root@slave-02 ~]# vim /etc/my.cnf [mysqld] server_id=103 log_bin=mysql_bin relay_log=relay_bin log_slave_updates=on gtid_mode=ON enforce_gtid_consistency=1
完成以上配置文件的修改後,分別重啓這三個節點上的MySQL服務:
[root@master ~]# systemctl restart mysqld [root@slave-01 ~]# systemctl restart mysqld [root@slave-02 ~]# systemctl restart mysqld
slave-01
對master
的主從關係進入slave-01
節點的MySQL命令行終端,分別執行以下語句來配置主從複製鏈路:
mysql> stop slave; -- 中止主從同步 mysql> change master to master_host='192.168.190.151', master_port=3306, master_user='repl', master_password='Abc_123456', master_auto_position=1; -- 配置master節點的鏈接信息 mysql> start slave; -- 啓動主從同步
配置完主從複製鏈路後,使用show slave status\G;
語句查看主從同步狀態,Slave_IO_Running
和Slave_SQL_Running
的值均爲Yes
才能表示主從同步狀態是正常的:
slave-02
對master
的主從關係一樣的步驟,進入slave-02
節點的MySQL命令行終端,分別執行以下語句來配置主從複製鏈路:
mysql> stop slave; -- 中止主從同步 mysql> change master to master_host='192.168.190.151', master_port=3306, master_user='repl', master_password='Abc_123456', master_auto_position=1; -- 配置master節點的鏈接信息 mysql> start slave; -- 啓動主從同步
配置完主從複製鏈路後,使用show slave status\G;
語句查看主從同步狀態,Slave_IO_Running
和Slave_SQL_Running
的值均爲Yes
才能表示主從同步狀態是正常的:
配置集羣內全部主機之間可以經過ssh
免密登陸,由於MHA是基於ssh
去實現遠程控制及數據管理的。例如,故障轉移過程當中保存原Master節點的二進制日誌以及配置虛擬IP等。
一、生成ssh
登陸密鑰:
[root@master ~]# ssh-keygen Generating public/private rsa key pair. Enter file in which to save the key (/root/.ssh/id_rsa): Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in /root/.ssh/id_rsa. Your public key has been saved in /root/.ssh/id_rsa.pub. The key fingerprint is: SHA256:LzRXziRQPrqaKEteH6KrZpCiV6uGP6GTi6RonE7Hhms root@master The key's randomart image is: +---[RSA 2048]----+ | ... | | o | | + o | | . B | | . S . o | |+ + . . = | |=Bo*o.. o . | |%EOo.+ + . | |%XB*. + | +----[SHA256]-----+
二、將密鑰拷貝到其餘服務器上:
[root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa root@192.168.190.151 [root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa root@192.168.190.152 [root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa root@192.168.190.154 [root@master ~]# ssh-copy-id -i /root/.ssh/id_rsa root@192.168.190.153
而後到集羣中其餘節點上進行一樣的操做,因爲是重複的操做這裏就不演示了。最後簡單測試下可否正常免密登陸便可:
[root@master ~]# ssh root@192.168.190.152 Last failed login: Sat Feb 1 15:29:38 CST 2020 from 192.168.190.151 on ssh:notty There was 1 failed login attempt since the last successful login. # 沒有要求輸入密碼,測試成功 Last login: Sat Feb 1 14:14:03 2020 from 192.168.190.1 [root@slave-01 ~]#
一、首先在全部的節點上安裝mha4mysql-node
軟件包,安裝包可到以下地址進行下載:
下載好的rpm
文件以下:
[root@master ~]# ls *.rpm mha4mysql-node-0.58-0.el7.centos.noarch.rpm [root@master ~]#
在安裝該rpm
包以前須要先安裝perl相關依賴:
[root@master ~]# yum -y install epel-release [root@master ~]# yum -y install perl-DBD-MySQL perl-DBI ncftp
如今就能夠安裝mha4mysql-node
了,命令以下:
[root@master ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
二、接着是在監控節點manager
上安裝mha4mysql-manager
軟件包,安裝包到以下地址進行下載:
下載好的rpm
文件以下:
[root@manager ~]# ls *.rpm mha4mysql-manager-0.58-0.el7.centos.noarch.rpm [root@manager ~]#
一樣,在安裝該rpm
包以前須要先安裝perl相關依賴:
[root@manager ~]# yum -y install epel-release [root@manager ~]# yum -y install perl-Config-Tiny perl-Time-HiRes perl-Parallel-ForkManager perl-Log-Dispatch perl-DBD-MySQL ncftp
而後安裝mha4mysql-manager
包,命令以下:
[root@manager ~]# rpm -ivh mha4mysql-manager-0.58-0.el7.centos.noarch.rpm
一、建立MHA的配置文件存放目錄和工做目錄:
[root@manager ~]# mkdir /etc/mha [root@manager ~]# mkdir /home/mysql_mha
二、建立MHA的配置文件,並添加以下內容:
[root@manager ~]# vim /etc/mha/mysql_mha.cnf [server default] # mha用於訪問數據庫的帳戶和密碼 user=mha password=Abc_123456 # 指定mha的工做目錄 manager_workdir=/home/mysql_mha # mha日誌文件的存放路徑 manager_log=/home/mysql_mha/manager.log # 指定mha在遠程節點上的工做目錄 remote_workdir=/home/mysql_mha # 可使用ssh登陸的用戶 ssh_user=root # 用於主從複製的MySQL用戶和密碼 repl_user=repl repl_password=Abc_123456 # 指定間隔多少秒檢測一次 ping_interval=1 # 指定master節點存放binlog日誌文件的目錄 master_binlog_dir=/var/lib/mysql # 指定一個腳本,該腳本實現了在主從切換以後,將虛擬IP漂移到新的Master上 master_ip_failover_script=/usr/bin/master_ip_failover # 指定用於二次檢查節點狀態的腳本 secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.190.151 -s 192.168.190.152 -s 192.168.190.154 # 配置集羣中的節點信息 [server1] hostname=192.168.190.151 # 指定該節點能夠參與Master選舉 candidate_master=1 [server2] hostname=192.168.190.152 candidate_master=1 [server3] hostname=192.168.190.154 # 指定該節點不能參與Master選舉 no_master=1
三、編寫配置文件中所配置的master_ip_failover
腳本,該腳本是根據MHA的官方示例修改的,MHA默認並無提供。須要注意腳本中的幾處地方須要根據實際狀況進行修改,已用註釋標明:
[root@manager ~]# vim /usr/bin/master_ip_failover #!/usr/bin/env perl use strict; use warnings FATAL => 'all'; use Getopt::Long; my ( $command, $orig_master_host, $orig_master_ip,$ssh_user, $orig_master_port, $new_master_host, $new_master_ip,$new_master_port, $orig_master_ssh_port,$new_master_ssh_port,$new_master_user,$new_master_password ); # 這裏定義的虛擬IP能夠根據實際狀況進行修改 my $vip = '192.168.190.80/24'; my $key = '1'; # 這裏的網卡名稱 「ens32」 須要根據你機器的網卡名稱進行修改 my $ssh_start_vip = "sudo /sbin/ifconfig ens32:$key $vip"; my $ssh_stop_vip = "sudo /sbin/ifconfig ens32:$key down"; my $ssh_Bcast_arp= "sudo /sbin/arping -I bond0 -c 3 -A $vip"; 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, 'orig_master_ssh_port=i' => \$orig_master_ssh_port, 'new_master_host=s' => \$new_master_host, 'new_master_ip=s' => \$new_master_ip, 'new_master_port=i' => \$new_master_port, 'new_master_ssh_port' => \$new_master_ssh_port, 'new_master_user' => \$new_master_user, 'new_master_password' => \$new_master_password ); exit &main(); sub main { $ssh_user = defined $ssh_user ? $ssh_user : 'root'; print "\n\nIN SCRIPT TEST====$ssh_user|$ssh_stop_vip==$ssh_user|$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(); &start_arp(); $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 \"`; } sub stop_vip() { `ssh $ssh_user\@$orig_master_host \" $ssh_stop_vip \"`; } sub start_arp() { `ssh $ssh_user\@$new_master_host \" $ssh_Bcast_arp \"`; } sub usage { print "Usage: master_ip_failover --command=start|stop|stopssh|status --ssh_user=user --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"; }
還須要給該腳本添加可執行權限,不然MHA是沒法調用的:
[root@manager ~]# chmod a+x /usr/bin/master_ip_failover
四、根據配置文件中remote_workdir
的配置,需在其餘節點上建立MHA的遠程工做目錄:
[root@master ~]# mkdir /home/mysql_mha [root@slave-01 ~]# mkdir /home/mysql_mha [root@slave-02 ~]# mkdir /home/mysql_mha
五、在配置文件中指定了讓manager
使用mha
這個用戶來訪問數據庫節點,因此須要在master
節點上建立mha
用戶:
create user 'mha'@'%' identified with mysql_native_password by 'Abc_123456'; grant all privileges on *.* to 'mha'@'%'; flush privileges;
六、完成以上全部步驟後,在manager
節點上使用masterha_check_ssh
和masterha_check_repl
對配置進行檢查,其中masterha_check_ssh
用於檢查ssh
登陸是否正常,而masterha_check_repl
則用於檢查主從節點的複製鏈路是否正常:
[root@manager ~]# masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf [root@manager ~]# masterha_check_repl --conf=/etc/mha/mysql_mha.cnf
執行結果以下:
七、以上檢測都經過後,就能夠啓動MHA服務了。啓動命令以下:
[root@manager ~]# nohup masterha_manager --conf=/etc/mha/mysql_mha.cnf &
啓動完成後,可使用ps
命令查看masterha_manager
進程是否存在,以下存在則表明啓動成功:
[root@manager ~]# ps aux |grep masterha_manager root 2842 0.3 1.1 299648 22032 pts/0 S 18:30 0:00 perl /usr/bin/masterha_manager --conf=/etc/mha/mysql_mha.cnf root 2901 0.0 0.0 112728 976 pts/0 R+ 18:31 0:00 grep --color=auto masterha_manager [root@manager ~]#
八、最後咱們須要到master
節點上,手動去配置虛擬IP。由於MHA只會在主從切換時漂移虛擬IP到新的Master節點,而不會在第一次啓動時主動去設置Master的虛擬IP,因此咱們須要手動設置。設置虛擬IP的命令以下:
[root@master ~]# ifconfig ens32:1 192.168.190.80/24
設置成功後,使用ip addr
命令能夠看到網卡上綁定的虛擬IP:
到此爲止,咱們就已經完成了MHA高可用架構的搭建,接下來咱們對其進行一些簡單的測試。例如,測試下是否能正常ping
通虛擬IP,畢竟應用端訪問數據庫時鏈接的是虛擬IP,因此首先得確保虛擬IP是可以被訪問的。以下:
能ping
通以後,使用Navicat等遠程鏈接工具測試下可否正常經過虛擬IP鏈接上數據庫:
肯定了虛擬IP能正常訪問後,接着測試MHA是否可以正常進行主從切換,首先將master
節點上的MySQL服務給停掉,模擬Master宕機:
[root@master ~]# systemctl stop mysqld
正常狀況下,此時master
節點上的網卡就不會再綁定該虛擬IP:
而是會被MHA漂移到slave-01
節點的網卡上,由於此時該Slave就是新的Master:
接着進入slave-02
節點上的MySQL命令行終端,確認下該Slave是否已經正常與新的Master進行同步。以前咱們配置slave-02
的主庫是master
,如今將master
停掉後,能夠看到slave-02
的Master_Host
已經被MHA切換成了slave-01
的IP:
通過以上測試後,能夠看到咱們搭建的MHA架構是可以正常運行的,已經使得Replication集羣擁有了基本的高可用能力,即使Master下線後也能正常從Slave中選舉新的Master並進行切換,也正確創建了其餘Slave與新Master的複製鏈路。
ssh
免密登陸,存在必定的安全隱患