MHA架構介紹
MHA是Master High Availability的縮寫芳撒,它是目前MySQL高可用方面的一個相對成熟的解決方案禀梳,其核心是使用perl語言編寫的一組腳本覆致,是一套優(yōu)秀的作為MySQL高可用性環(huán)境下故障切換和主從提升的高可用軟件愈涩。在MySQL故障切換過程中望抽,MHA能做到在0~30秒之內自動完成數(shù)據(jù)庫的故障切換操作,并且能在最大程度上保證數(shù)據(jù)的一致性履婉,以達到真正意義上的高可用煤篙。
基于MHA的架構不像MMM那樣需要搭建主主復制,只需要搭建基本的主從復制架構即可毁腿。因為MHA在主庫掛掉時辑奈,是在多個從庫中選取出一個從庫作為新的主庫。MHA集群中的各節(jié)點彼此之間均需要基于ssh
互信通信已烤,以實現(xiàn)遠程控制及數(shù)據(jù)管理功能鸠窗。
MHA提供了什么功能:
- 可以監(jiān)控Master節(jié)點是否可用
- 當Master不可用時,能在多個Slave中選舉出新的Master
- 提供了主從切換和故障轉移功能胯究,MHA會嘗試在宕機的Master上保存binlog稍计,在最大程度上保證事務不丟失。但如果是Master所在的服務器已經無法訪問唐片,或硬件層面出現(xiàn)了問題丙猬,則無法成功保存binlog
- MHA可以與半同步復制結合,避免從庫之間出現(xiàn)數(shù)據(jù)不一致的情況
- 支持MySQL基于GTID和基于日志點的兩種復制方式
MHA故障轉移過程:
- 嘗試使用
ssh
登錄到宕機崩潰的Master節(jié)點上保存二進制日志事件(binlog events); - 從多個Slave中識別含有最新更新的Slave费韭,將其作為備選的Master;
- 然后基于該Slave同步差異的中繼日志(relaylog)到其他的Slave上庭瑰;
- 接著同步從原Master上保存的二進制日志事件(binlog events)星持;
- 將備選的Master提升為新的Master;
- 使其他的Slave連接新的Master進行復制弹灭;
- 在新的Master啟動vip地址督暂,保證前端請求可以發(fā)送到新的Master。
MHA的架構圖如下:
動手搭建MHA架構
本文中所使用的機器說明:
名稱 | IP | 角色 |
---|---|---|
master | 192.168.190.151 | 主庫 |
slave-01 | 192.168.190.152 | 從庫 |
slave-02 | 192.168.190.154 | 從庫 |
manager | 192.168.190.153 | 集群管理節(jié)點(MHA) |
環(huán)境版本說明:
- 操作系統(tǒng)版本:CentOS 7
- MySQL版本:8.0.19
- MHA版本:0.58
另外的說明:
- 會來了解MMM架構的小伙伴們想必都已經掌握了MySQL的安裝方式穷吮,而且介紹MySQL的安裝也有很多文章逻翁,所以本文為了減少不必要的篇幅就不演示MySQL的安裝了,文中所用到的機器都已經提前安裝好了MySQL捡鱼。
配置主從節(jié)點的配置文件
1八回、在所有主從節(jié)點上使用如下語句創(chuàng)建用于主從復制的MySQL用戶,因為每個從庫都有可能會被選舉為主庫,所以都需要擁有用于復制的用戶:
create user 'repl'@'%' identified with mysql_native_password by 'Abc_123456';
grant replication slave on *.* to 'repl'@'%';
flush privileges;
2缠诅、然后修改master
節(jié)點上的MySQL配置文件:
[root@master ~]# vim /etc/my.cnf
[mysqld]
# 設置當前節(jié)點的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
3管引、在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
4、接著是配置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
完成以上配置文件的修改后褥伴,分別重啟這三個節(jié)點上的MySQL服務:
[root@master ~]# systemctl restart mysqld
[root@slave-01 ~]# systemctl restart mysqld
[root@slave-02 ~]# systemctl restart mysqld
配置slave-01
對master
的主從關系
進入slave-01
節(jié)點的MySQL命令行終端谅将,分別執(zhí)行如下語句來配置主從復制鏈路:
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節(jié)點的連接信息
mysql> start slave; -- 啟動主從同步
配置完主從復制鏈路后,使用show slave status\G;
語句查看主從同步狀態(tài)重慢,Slave_IO_Running
和Slave_SQL_Running
的值均為Yes
才能表示主從同步狀態(tài)是正常的:
配置slave-02
對master
的主從關系
同樣的步驟饥臂,進入slave-02
節(jié)點的MySQL命令行終端,分別執(zhí)行如下語句來配置主從復制鏈路:
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節(jié)點的連接信息
mysql> start slave; -- 啟動主從同步
配置完主從復制鏈路后伤锚,使用show slave status\G;
語句查看主從同步狀態(tài)擅笔,Slave_IO_Running
和Slave_SQL_Running
的值均為Yes
才能表示主從同步狀態(tài)是正常的:
配置ssh免密登錄
配置集群內所有主機之間能夠通過ssh
免密登錄,因為MHA是基于ssh
去實現(xiàn)遠程控制及數(shù)據(jù)管理的屯援。例如猛们,故障轉移過程中保存原Master節(jié)點的二進制日志以及配置虛擬IP等。
1狞洋、生成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]-----+
2弯淘、將密鑰拷貝到其他服務器上:
[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
然后到集群中其他節(jié)點上進行同樣的操作,由于是重復的操作這里就不演示了吉懊。最后簡單測試下能否正常免密登錄即可:
[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 ~]#
安裝MHA軟件包
1、首先在所有的節(jié)點上安裝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
現(xiàn)在就可以安裝mha4mysql-node
了态鳖,命令如下:
[root@master ~]# rpm -ivh mha4mysql-node-0.58-0.el7.centos.noarch.rpm
- Tips:另外的兩個Slave節(jié)點和監(jiān)控節(jié)點按如上步驟安裝即可,這里就不重復演示了
2恶导、接著是在監(jiān)控節(jié)點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管理節(jié)點
1邦泄、創(chuàng)建MHA的配置文件存放目錄和工作目錄:
[root@manager ~]# mkdir /etc/mha
[root@manager ~]# mkdir /home/mysql_mha
2、創(chuàng)建MHA的配置文件裂垦,并添加如下內容:
[root@manager ~]# vim /etc/mha/mysql_mha.cnf
[server default]
# mha用于訪問數(shù)據(jù)庫的賬戶和密碼
user=mha
password=Abc_123456
# 指定mha的工作目錄
manager_workdir=/home/mysql_mha
# mha日志文件的存放路徑
manager_log=/home/mysql_mha/manager.log
# 指定mha在遠程節(jié)點上的工作目錄
remote_workdir=/home/mysql_mha
# 可以使用ssh登錄的用戶
ssh_user=root
# 用于主從復制的MySQL用戶和密碼
repl_user=repl
repl_password=Abc_123456
# 指定間隔多少秒檢測一次
ping_interval=1
# 指定master節(jié)點存放binlog日志文件的目錄
master_binlog_dir=/var/lib/mysql
# 指定一個腳本顺囊,該腳本實現(xiàn)了在主從切換之后,將虛擬IP漂移到新的Master上
master_ip_failover_script=/usr/bin/master_ip_failover
# 指定用于二次檢查節(jié)點狀態(tài)的腳本
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.190.151 -s 192.168.190.152 -s 192.168.190.154
# 配置集群中的節(jié)點信息
[server1]
hostname=192.168.190.151
# 指定該節(jié)點可以參與Master選舉
candidate_master=1
[server2]
hostname=192.168.190.152
candidate_master=1
[server3]
hostname=192.168.190.154
# 指定該節(jié)點不能參與Master選舉
no_master=1
3蕉拢、編寫配置文件中所配置的master_ip_failover
腳本特碳,該腳本是根據(jù)MHA的官方示例修改的诚亚,MHA默認并沒有提供。需要注意腳本中的幾處地方需要根據(jù)實際情況進行修改测萎,已用注釋標明:
[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可以根據(jù)實際情況進行修改
my $vip = '192.168.190.80/24';
my $key = '1';
# 這里的網卡名稱 “ens32” 需要根據(jù)你機器的網卡名稱進行修改
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";
}
還需要給該腳本添加可執(zhí)行權限亡电,否則MHA是無法調用的:
[root@manager ~]# chmod a+x /usr/bin/master_ip_failover
4、根據(jù)配置文件中remote_workdir
的配置硅瞧,需在其他節(jié)點上創(chuàng)建MHA的遠程工作目錄:
[root@master ~]# mkdir /home/mysql_mha
[root@slave-01 ~]# mkdir /home/mysql_mha
[root@slave-02 ~]# mkdir /home/mysql_mha
5份乒、在配置文件中指定了讓manager
使用mha
這個用戶來訪問數(shù)據(jù)庫節(jié)點,所以需要在master
節(jié)點上創(chuàng)建mha
用戶:
create user 'mha'@'%' identified with mysql_native_password by 'Abc_123456';
grant all privileges on *.* to 'mha'@'%';
flush privileges;
6腕唧、完成以上所有步驟后或辖,在manager
節(jié)點上使用masterha_check_ssh
和masterha_check_repl
對配置進行檢查,其中masterha_check_ssh
用于檢查ssh
登錄是否正常枣接,而masterha_check_repl
則用于檢查主從節(jié)點的復制鏈路是否正常:
[root@manager ~]# masterha_check_ssh --conf=/etc/mha/mysql_mha.cnf
[root@manager ~]# masterha_check_repl --conf=/etc/mha/mysql_mha.cnf
執(zhí)行結果如下:
7颂暇、以上檢測都通過后,就可以啟動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 ~]#
8膀曾、最后我們需要到master
節(jié)點上县爬,手動去配置虛擬IP。因為MHA只會在主從切換時漂移虛擬IP到新的Master節(jié)點添谊,而不會在第一次啟動時主動去設置Master的虛擬IP财喳,所以我們需要手動設置。設置虛擬IP的命令如下:
[root@master ~]# ifconfig ens32:1 192.168.190.80/24
設置成功后斩狱,使用ip addr
命令可以看到網卡上綁定的虛擬IP:
測試MHA服務
到此為止耳高,我們就已經完成了MHA高可用架構的搭建,接下來我們對其進行一些簡單的測試所踊。例如泌枪,測試下是否能正常ping
通虛擬IP,畢竟應用端訪問數(shù)據(jù)庫時連接的是虛擬IP秕岛,所以首先得確保虛擬IP是能夠被訪問的工闺。如下:
能ping
通之后,使用Navicat等遠程連接工具測試下能否正常通過虛擬IP連接上數(shù)據(jù)庫:
確定了虛擬IP能正常訪問后瓣蛀,接著測試MHA是否能夠正常進行主從切換,首先將master
節(jié)點上的MySQL服務給停掉雷厂,模擬Master宕機:
[root@master ~]# systemctl stop mysqld
正常情況下惋增,此時master
節(jié)點上的網卡就不會再綁定該虛擬IP:
而是會被MHA漂移到slave-01
節(jié)點的網卡上,因為此時該Slave就是新的Master:
接著進入slave-02
節(jié)點上的MySQL命令行終端改鲫,確認下該Slave是否已經正常與新的Master進行同步诈皿。之前我們配置slave-02
的主庫是master
林束,現(xiàn)在將master
停掉后,可以看到slave-02
的Master_Host
已經被MHA切換成了slave-01
的IP:
經過以上測試后稽亏,可以看到我們搭建的MHA架構是能夠正常運行的壶冒,已經使得Replication集群擁有了基本的高可用能力,即便Master下線后也能正常從Slave中選舉新的Master并進行切換截歉,也正確建立了其他Slave與新Master的復制鏈路胖腾。
MHA架構優(yōu)缺點
優(yōu)點:
- 使用Perl腳本語言開發(fā)并且完全開源,開發(fā)者可以根據(jù)自己的需求進行二次開發(fā)
- 能夠支持基于GTID和基于日志點的復制模式
- MHA在進行故障轉移時更不易產生數(shù)據(jù)丟失
- 在一個監(jiān)控節(jié)點上可以監(jiān)控多個Replication集群
缺點:
- MHA默認不提供虛擬IP功能瘪松,需要自行編寫腳本或利用第三方工具來實現(xiàn)虛擬IP的配置
- MHA啟動后只會對Master進行監(jiān)控咸作,不會對Slave進行監(jiān)控,也無法監(jiān)控復制鏈路的情況
- 集群環(huán)境需要能夠通過
ssh
免密登錄宵睦,存在一定的安全隱患 - MHA沒有提供對Slave的讀負載均衡功能记罚,需要通過第三方工具來實現(xiàn)