Step By Step 搭建 MySql MHA 集群
關于MHA
?? MHA(Master High Availability)是一款開源的mysql高可用程序,目前在mysql高可用方面是一個相對成熟的解決方案。MHA 搭建的前提是MySQL集群中已經搭建了MySql Replication環境,有了Master/Slave節點。MHA的主要作用就是監測到Master節點故障時會提升主從復制環境中擁有最新數據的Slave節點成為新的master節點。同時,在切換master期間,MHA會通過從其他的Slave節點來獲取額外的信息來避免一致性的問題,整個的切換過程對于應用程序而言是完全透明的。MHA還提供了master節點在線切換功能,即按需切換master/slave節點。
MHA Manager 和 MHA Node
MHA 服務有兩個角色,MHA Manager?和?MHA Node?
?MHA Manager: 通常單獨部署在一臺獨立機器上管理 master/slave 集群,每個master/slave 集群可以理解為一個application。
???MHA Node: 運行在每臺mysql 服務器(master/slave)上。它通過監控具備解析和清理logs功能來加快故障轉移。
整體上的架構如下圖所示。
?? MHA 在自動切換的過程中會從宕掉的MySql master節點中保存二進制日志,以保證數據的完整性。但是如果master節點直接宕機了呢,或者網絡直接不能聯通了呢?MHA就沒有辦法獲取master的二進制日志,也就沒有辦法保證數據的完整性了。這也就是為什么MHA應該與MySql主從復制結合起來。這樣的話,只要有一個slave節點從master節點復制到了最新的日志,MHA就可以將最近的二進制日志應用到其他的slave節點上,這樣就可以最大限度上保證數據的完整性。
MHA 自動切換的原理可以總結為下面幾點.
- 從宕機崩潰的master保存二進制日志事件(binlog events);
- 識別含有最新更新的slave;
- 應用差異的中繼日志(relay log)到其他的slave;
- 應用從master保存的二進制日志事件(binlog events);
- 提升一個slave為新的master;
- 使其他的slave連接新的master進行復制;
MHA 工具組件
MHA?提供了很多的程序組件,通過這些組件,我們 可以很方便的管理MHA集群。
Manager節點:
- masterha_check_ssh:MHA依賴的環境監測工具;
- masterha_check_ssh: MySql復制環境檢測工具;
- masterha_manager: MHA 服務主程序;
- masterha_check_status: MHA運行狀態探測工具;
- masterha_master_monitor: MySql master節點可用性檢測工具;
- masterha_switch: master 節點切換工具;
- masterha_conf_host: 添加或刪除配置的節點;
- masterha_stop: 關閉MHA服務的工具;
Node節點:
- save_binary_logs:保存和復制master節點的二進制日志;
- apply_diff_relay_logs: 識別差異的中繼日志事件并應用于其他的slave;
- purge_relay_logs:清除中集日志(不會阻塞SQL線程);
實驗介紹
?? 在實際的生產環境中有很多的因素需要考慮,例如MHA Manager的單點問題。但是我們由于環境有限,所以就暫時不考慮這些。此次實驗中實驗環境如下。
| MHA Manager | manager | 192.168.0.20 | MHA Manager,控制Master節點故障轉移 | mha4mysql-manager-0.56-0.el6.noarch |
| MySql Master | master | 192.168.0.21 | MySql Master 節點 | Mariadb-server-5.5.56-2.el7 |
| MySql Slave | Slave1 | 192.168.0.22 | Mysql Repliaction集群中的Slave1 節點 | Mariadb-server-5.5.56-2.el7 |
| MySql Slave | Slave2 | 192.168.0.26 | MySql Repliaction 集群中的Slave2節點 | Mariadb-server-5.5.56-2.el7 |
準備MySql Replication 環境
安裝PLUGIN
?? 某種意義上說,Master節點不會一直充當master節點。Master節點從故障狀態中恢復之后,很有可能充當的是slave節點,所以我們在安裝插件的時候,不做區別對待。?
mysql 支持多種插件/var/lib/mysql/plugin 目錄下,需要安裝方可使用。在Master(192.168.0.21),和Slave(192.168.0.22,192.168.0.26)節點上安裝semisync_master.so?semisync_slave.so?兩個插件。
然后在三臺主機上開啟下面兩個參數
MariaDB [(none)]> SET GLOBAL rpl_semi_sync_master_enabled=ON; Query OK, 0 rows affected (0.00 sec)MariaDB [(none)]> SET GLOBAL rpl_semi_sync_slave_enabled=ON; Query OK, 0 rows affected (0.00 sec)MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%'; +------------------------------------+-------+ | Variable_name | Value | +------------------------------------+-------+ | rpl_semi_sync_master_enabled | ON | | rpl_semi_sync_master_timeout | 10000 | | rpl_semi_sync_master_trace_level | 32 | | rpl_semi_sync_master_wait_no_slave | ON | | rpl_semi_sync_slave_enabled | ON | | rpl_semi_sync_slave_trace_level | 32 | +------------------------------------+-------+ 6 rows in set (0.00 sec)到目前而言,三臺主機之間沒有差別,也沒有角色上的區分。接下來我們開始設置master與slave來實現主從復制。
編輯 /etc/my.cnf.d/server.cnf 文件,加入下面這樣一段配置
[mariadb] server-id=1 #Master設置1,Slave1設置2,Slave2設置3 log-bin=mysql-bin relay-log=mysql-relay-bin relay_log_purge=0修改完配置文件之后,重啟Mariadb.?systemctl restart mariadb
在master節點上進行操作
# 這里需要記住 File 以及Position的數據,在SLAVE 節點上要用到 MariaDB [(none)]> show master status; +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000001 | 245 | | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) MariaDB [(none)]> GRANT REPLICATION MASTER ON *.* TO 'repl'@'%' IDENTIFIED BY '123'; Query OK, 0 rows affected (0.00 sec)MariaDB [(none)]> FLUSH PRIVILEGES; Query OK, 0 rows affected (0.00 sec)在slave節點上進行操作
MariaDB [(none)]> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%' IDENTIFIED BY '123'; Query OK, 0 rows affected (0.01 sec)MariaDB [(none)]> CHANGE MASTER TO-> MASTER_HOST='192.168.0.21',-> MASTER_PORT=3306,-> MASTER_USER='repl',-> MASTER_PASSWORD='123',-> MASTER_LOG_FILE='mysql-bin.000001', -> MASTER_LOG_POS=245; Query OK, 0 rows affected (0.03 sec)MariaDB [(none)]> start slave; Query OK, 0 rows affected (0.00 sec)上面的操作完成后,在master主機上查看master的狀態。
MariaDB [(none)]> SHOW SLAVE HOSTS; +-----------+------+------+-----------+ | Server_id | Host | Port | Master_id | +-----------+------+------+-----------+ | 3 | | 3306 | 1 | | 2 | | 3306 | 1 | +-----------+------+------+-----------+在slave主機上可以查看slave主機的狀態。
*************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.0.21Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000001Read_Master_Log_Pos: 245..........................Slave_IO_Running: YesSave_SQL_Running: Yes.............在Master節點上創建MHA監控所需要的用戶,該用戶會同步到slave端。
MariaDB [(none)]> GRANT ALL PRIVILEGES ON *.* TO 'mha_rep'@'%' IDENTIFIED BY '123'; MariaDB [(none)]> flush privileges;至此,MySql 主從復制環境就搭建好了。下面就可以開始來安裝MHA了。
注:在查看slave節點狀態時,如果出現問題,可以檢查一下SELinux,iptables,以及其他權限問題,在實驗開始之前,最好先將這些環境設置好,避免出現問題。
安裝配置MHA
設置SSH免密通信
?? MHA 集群中的各節點之間需要基于SSH互相通信,以實現遠程控制以及數據管理功能。簡單起見,我們以Manager節點為例,然后將生成的文件發送到需要管理的主機上。四個節點都需要進行這個操作。
[root@manager ~]# ssh-keygen -t rsa [root@manager ~]# for i in 21 22 26;do ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.0.$i; done?? 這樣MHA Manager就實現了通過SSH免密管理其他的mysql節點
安裝MHA
?? MHA 官方提供了rpm的安裝包,通過搜索可以找到。CentOS 7 可以直接使用el6 的rpm安裝包。下面是本次實驗中rpm安裝包的下載地址。https://github.com/yoshinorim/mha4mysql-manager/wiki/Downloads。
在所有節點上安裝node安裝包
[root@manager ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm在Manager節點上安裝manager安裝包
[root@manager ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm??還可以在上述網站上下載源碼包,里面有很多的例子和腳本可以直接拿來使用。 將下載的源碼包解壓之后在samples/scripts下的所有腳本復制到/usr/bin目錄(因為安裝的mha manager的相關命令就在/usr/bin/目錄下,可以使用rpm -ql mha4mysql-manager-0.56-0.el6 來查看)下。?
腳本如下:
?? 這里有一點需要注意,拷貝到/usr/bin 目錄下的文件如果沒有執行權限,要加上執行權限。
初始化MHA
?? Manager節點需要為每個監控的master/slave 集群提供專用的配置文件,而所有的master/slave集群也可以共享全局配置。全局配置文件默認在/etc/masterha_default.cnf,其為可選配置。如果僅監控一組master/slave集群,也可以直接通過application 的配置來提供給個服務器的默認配置信息。而滅個application的配置文件路徑為自定義,我們的實例中,只有一個master/slave集群,所以我們就定義一個配置文件好了。
[root@manager ~]# cat /etc/masterha/app1.cnf[server default] manager_workdir=/etc/masterha manager_log=/etc/masterha/manager.log user=mha_rep password=123 ping_interval=3 remote_workdir=/etc/masterha repl_user=repl repl_password=123 ssh_user=root master_ip_failover_script=/usr/bin/master_ip_failover master_ip_online_change_script=/usr/bin/master_ip_online_change report_script=/usr/bin/send_report shutdown_script="" secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.0.22 -s 192.168.0.26 --user=root --master_host=192.168.0.21 --master_ip=192.168.0.21 --master_port=3306[server1] hostname=192.168.0.21 port=3306 master_binlog_dir=/var/lib/mysql/ candidate_master=1 check_repl_delay=0 [server2] hostname=192.168.0.22 port=3306 master_binlog_dir=/var/lib/mysql/ candidate_master=1 check_repl_delay=0[server3] hostname=192.168.0.26 port=3306 master_binlog_dir=/var/lib/mysql/ no_master=1?? 編輯一下 /etc/masterha_default.cnf 文件,添加一些全局的配置。配置文件的內容如下。
[root@manager ~]# cat /etc/masterha_default.cnf [server default] user=mha_rep password=123 repl_user=repl repl_password=123 ssh_user=root ping_interval=3 master_binlog_dir=/var/lib/mysql remote_workdir=/etc/masterha secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.0.22 -s 192.168.0.26 --user=root --master_host=192.168.0.21 --master_ip=192.168.0.21 --master_port=3306 設置自動failover時候的切換腳本; master_ip_failover_script=/usr/bin/master_ip_failover 設置手動切換時候的切換腳本; master_ip_online_change_script=/usr/bin/master_ip_online_change 設置發生切換后發送的報警的腳本; report_script=/usr/bin/send_report 設置故障發生后關閉故障主機腳本(該腳本的主要作用是關閉主機防止發生腦裂,這里沒有使用); shutdown_script=""檢查mysqlbinlog mysql 命令
?? 在master,slave1 和slave2 節點上執行下面的命令檢查一下mysqlbinlog和mysql 命令的位置。
[root@master ~]# type mysqlbinlog mysqlbinlog is /usr/bin/mysqlbinlog [root@master ~]# type mysql mysql is /usr/bin/mysql?? 一定要確保 mysqlbinlog 和mysql 兩個命令在 /usr/bin 目錄下。由于我安裝的是mariadb ,所以這兩個文件默認就在這兩個目錄,如果是其他版本的mysql,不在這兩個目錄下的話可以使用軟連接的方式,在這個目錄下添加兩個軟連接。
否則,在進行檢查的時候,會出現如下的類似錯誤。
mysqlbinlog
.....Can't exec "mysqlbinlog": No suchfile or directory at /usr/local/share/perl5/MHA/BinlogManager.pm line 106. mysqlbinlog version command failed with rc1:0, please verify PATH, LD_LIBRARY_PATH, and client options.....mysql
..... Testing mysql connection and privileges..sh: mysql: command not found mysql command failed with rc 127:0! .....配置VIP
?? 在master 節點上進行操作,給ens33網卡添加一個VIP,這樣用戶訪問的時候,就會可以通過VIP進行訪問,并不需要關心MySQL集群中的具體細節。同時如果master宕機之后,VIP會自動進行轉移,并不會影響到用戶的訪問,后端VIP漂移的過程對用戶來說完全透明。
[root@manager ~]# ifconfig ens33:1 192.168.0.88?? 在MHA manager上進行操作,修改/usr/bin/master_ip_failover腳本如下,主要是VIP的修改。
[root@centos7-1 ~]# cat /usr/bin/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 );my $vip = '192.168.0.88/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" ) {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";# 這一行很重要,表示在master上mysql服務停止之后,關閉掉VIP,以免地址沖突&stop_vip();&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";exit 0;}else {&usage();exit 1;} }sub start_vip() {`ssh $ssh_user\@$new_master_host \" $ssh_start_vip \"`; } sub stop_vip() {return 0 unless ($ssh_user);`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"; }驗證MHA
?? 經過上述的一系列的的配置和操作,我們就順利的配置好了MySql replication 環境和MHA 環境,接下來開始驗證一下。?
在MHA manager 上進行一下下面的操作。
啟動MHA
?? 在manager 節點上進行操作。
[root@manager ~]# nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null > /etc/masterha/manager.log 2>&1 & [1] 7861 [root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf app1 (pid:7861) is running(0:PING_OK), master:192.168.0.21停止MHA
?? 如果想要停止MHA 可以執行如下的命令
[root@manager ~]# masterha_stop --conf=/etc/masterha/app1.cnf Stopped app1 successfully. [1]+ Exit 1 nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null > /etc/masterha/manager.log 2>&1MHA 測試故障轉移
在master節點關閉mariadb 服務
systemctl stop mariadb在Manager 節點查看/etc/masterha/manager.log
?? 在manager節點查看 manager.log 的日志,可以看到下面的切換過程
----- Failover Report -----app1: MySQL Master failover 192.168.0.21(192.168.0.21:3306) to 192.168.0.22(192.168.0.22:3306) succeededMaster 192.168.0.21(192.168.0.21:3306) is down!Check MHA Manager logs at manager:/etc/masterha/manager.log for details.Started automated(non-interactive) failover. Invalidated master IP address on 192.168.0.21(192.168.0.21:3306) The latest slave 192.168.0.22(192.168.0.22:3306) has all relay logs for recovery. Selected 192.168.0.22(192.168.0.22:3306) as a new master. 192.168.0.22(192.168.0.22:3306): OK: Applying all logs succeeded. 192.168.0.22(192.168.0.22:3306): OK: Activated master IP address. 192.168.0.26(192.168.0.26:3306): This host has the latest relay log events. Generating relay diff files from the latest slave succeeded. 192.168.0.26(192.168.0.26:3306): OK: Applying all logs succeeded. Slave started, replicating from 192.168.0.22(192.168.0.22:3306) 192.168.0.22(192.168.0.22:3306): Resetting slave info succeeded. Master failover to 192.168.0.22(192.168.0.22:3306) completed successfully.注意,故障轉移完成之后,manager會自動停止,此時使用masterha_check_status命令檢測將會是下面這種結果.
[root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf app1 is stopped(2:NOT_RUNNING).在新的Master上進行驗證
?? 在新的master主機slave1上進行查看,master_id 已經進行了切換,并且少了一臺slave 主機。
MariaDB [(none)]> show slave hosts; +-----------+------+------+-----------+ | Server_id | Host | Port | Master_id | +-----------+------+------+-----------+ | 3 | | 3306 | 2 | +-----------+------+------+-----------+ 1 row in set (0.00 sec)?? 在slave2主機上查看slave 的當前狀態 。
MariaDB [(none)]> show slave status\G *************************** 1. row ***************************Slave_IO_State: Waiting for master to send eventMaster_Host: 192.168.0.22Master_User: replMaster_Port: 3306Connect_Retry: 60Master_Log_File: mysql-bin.000004Read_Master_Log_Pos: 384Relay_Log_File: mysql-relay-bin.000002Relay_Log_Pos: 529Relay_Master_Log_File: mysql-bin.000004Slave_IO_Running: YesSlave_SQL_Running: Yes.......................?? 可以看到最新的master的IP 已經變成了之前slave1 主機的IP地址,這說明master 切換成功。
在新Master主機上查看VIP遷移,舊master主機上查看IP
?? 在新的master 主機上查看ip地址的變化,如果VIP 漂移成功說明,之前的配置沒有問題。
[root@slave1 ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:50:56:37:c4:5e brd ff:ff:ff:ff:ff:ffinet 192.168.0.88/24 brd 192.168.0.255 scope global ens33:1valid_lft forever preferred_lft foreverinet 192.168.0.22/24 brd 192.168.0.255 scope global secondary dynamic ens33valid_lft 6390sec preferred_lft 6390secinet6 fe80::e9cb:24a6:f81d:1810/64 scope link valid_lft forever preferred_lft forever?? 在舊的master主機上查看VIP是否已經被移除。
[root@master ~]# ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00inet 127.0.0.1/8 scope host lovalid_lft forever preferred_lft foreverinet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000link/ether 00:50:56:29:d0:2d brd ff:ff:ff:ff:ff:ffinet 192.168.0.21/24 brd 192.168.0.255 scope global dynamic ens33valid_lft 7198sec preferred_lft 7198secinet6 fe80::c28a:e648:5959:5ad6/64 scope link valid_lft forever preferred_lft forever?? 如果上面兩項的檢測都沒有問題,說明在實際的使用過程中VIP 就不會產生地址沖突了。 而且地址切換過程對用戶來說,基本上沒有任何感知,這樣就保證了mysql服務的高可用了。
搶救故障節點,重新加入集群
?? 生產中mysql服務停掉可以立即監監控到,而且這基本上屬于以及故障需要立即進行排除。?
重新恢復宕掉的mysql服務比較好的思路是,將其基于最新的master節點的數據備份進行數據恢復,然后重新啟動服務,將其設置為slave節點,并加入到新的master集群,之后重啟MHA監控。?
備份還原過程,此處不再贅述。將啟動后的節點重新加入到新的master集群中。過程與之前介紹的類似。
?? 在新的master節點上查看最新的slave主機狀態。
MariaDB [(none)]> show slave hosts; +-----------+------+------+-----------+ | Server_id | Host | Port | Master_id | +-----------+------+------+-----------+ | 1 | | 3306 | 2 | | 3 | | 3306 | 2 | +-----------+------+------+-----------+ 2 rows in set (0.00 sec)?? 可以看到slave 主機的server_id 已經變化了。
在manager主機上檢查MHA
?? 在manager上修改/etc/masterha/app1.cnf中secondary_check_script中的master IP值,將新的master ip修改上
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.0.21 -s 192.168.0.26 --user=root --master_host=192.168.0.22 --master_ip=192.168.0.22 --master_port=3306?? 修改/etc/masterha_default.cnf 中secondary_check_script 中的IP地址
secondary_check_script=/usr/bin/masterha_secondary_check -s 192.168.0.21 -s 192.168.0.26 --user=root --master_host=192.168.0.22 --master_ip=192.168.0.22 --master_port=3306?? 在Manager 上啟動MHA 然后檢查MHA的狀態
[root@centos7-1 ~]# masterha_check_repl --conf=/etc/masterha/app1.cnf .........192.168.0.22(192.168.0.22:3306) (current master)+--192.168.0.21(192.168.0.21:3306)+--192.168.0.26(192.168.0.26:3306)......MySQL Replication Health is OK.?? 啟動MHA ,檢查MHA的狀態
[root@manager ~]# nohup masterha_manager --conf=/etc/masterha/app1.cnf < /dev/null > /etc/masterha/manager.log 2>&1 & [1] 9186 [root@manager ~]# masterha_check_status --conf=/etc/masterha/app1.cnf app1 (pid:9186) is running(0:PING_OK), master:192.168.0.22總結
至此,MySql MHA 的配置與測試基本就完成了。在實際生產中,至少也應該對MySQL主從復制進行一下驗證,并且對MySQL 故障進行了解,以便在實際生產中能夠有效的排除故障。
? ? ?本文轉自Eumenides_s 51CTO博客,原文鏈接:
http://blog.51cto.com/xiaoshuaigege/2060768,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Step By Step 搭建 MySql MHA 集群的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: usermod命令,用户密码管理,mkp
- 下一篇: 初学APP总结