MHA高可用 MHA+Keepalive
MHA高可用
MHA簡介
MHA(Master High Availability)目前在SQL/">MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟體。
在MySQL故障切換過程中,MHA能做到在10~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。
該軟體由兩部分組成:MHA Manager(管理節點)和MHA Node(資料節點)。
MHA功能
MHA能夠在較短的時間內實現自動故障檢測和故障轉移,通常在10-30秒以內;
在複製框架中,MHA能夠很好地解決複製過程中的資料一致性問題,由於不需要在現有的 replication中新增額外的伺服器,僅需要一個manager節點,而一個Manager能管理多套複製,所以能大大地節約伺服器的數量
另外,安裝簡單,無效能損耗,以及不需要修改現 有的複製部署也是它的優勢之處。
MHA還提供線上主庫切換的功能,能夠安全地切換當前執行的主庫到一個新的主庫中 (通過將從庫提升為主庫),大概0.5-2秒內即可完成。
MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上,MHA Manager會定時探測叢集中的master節點,當master出現故障時,它可以自動將最新資料的slave提升為新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。
MHA工作原理
工作原理說明:
1、儲存master上的所有binlog事件
2、找到含有最新binlog位置點的slave
3、通過中繼日誌將資料恢復到其他的slave
4、將包含最新binlog位置點的slave提升為master
5、將其他從庫slave指向新的master原slave01 並開啟主從複製
6、將儲存下來的binlog恢復到新的master上
MHA工具介紹
MHA軟體由兩部分組成,Manager工具包和Node工具包
masterha_check_ssh#檢査 MHA 的 ssh-key masterha_check_repl#檢査主從複製情況 masterha_manger#啟動MHA masterha_check_status#檢測MHA的執行狀態^ masterha_mast er_monitor#檢測master是否宕機 masterha_mast er_switch#手動故障轉移— masterha_conf_host#手動新增server倍息 masterha_secondary_check#建立TCP連線從遠端伺服器v masterha_stop#停止MHA
Node工具包主要包括以下幾個工具:
save_binary_1ogs#儲存宕機的master的binlog apply_diff_relay_logs#識別relay log的差異 filter_mysqlbinlog#防止回滾事件一MHA已不再使用這個工具 purge_relay_logs#清除中繼曰志一不會阻塞SQL執行緒
MHA的優點
1、自動故障轉移
2、主庫崩潰不存在資料不一致的情況
3、不需要對當前的mysql環境做重大修改
4、不需要新增額外的伺服器
5、效能優秀,可以工作再半同步和非同步複製框架
6、只要replication支援的儲存引擎mha都支援
MHA部署
本次部署包括 mysql主從同步+MHA高可用+keepalived
mha版本0.56
資料庫5.7
機器名 IP地址 功能劃分
db01 172.16.1.51 主 keepalived node
db02 172.16.1.52 從 keepalived node
db03 172.16.1.53 從 manager node
基礎環境部署
基礎內容
關閉防火牆和selinux
systemctl stop firewalld && setenforce 0
下載資料庫
安裝mysql, 預設5.7版本, 使用本地yum源下載
yum install mysql-community-server -y
修改配置檔案
修改配置檔案/etc/my.cnf server-id 以IP最後一段命名
db01的內容
[root@db01 ~]# vi /etc/my.cnf#使用vi開啟 [mysqld] server-id=51 log-bin = master-log relay-log = relay-log skip_name_resolve
db02的內容
[root@db02 ~]# vi /etc/my.cnf server-id=52 relay-log = relay-log log-bin = master-log read_only = ON relay_log_purge = 0 skip_name_resolve log_slave_updates = 1
db03的內容
[root@db03 ~]# vi /etc/my.cnf [mysqld] server-id = 53 relay-log = relay-log log-bin = master-log read_only = ON relay_log_purge = 0 skip_name_resolve log_slave_updates = 1
啟動資料庫, 並加入開機自啟動
systemctl start mysqld && systemctl enable mysqld
修改密碼及匯入資料
修改密碼
登陸mysql資料庫[password中填寫上一步過濾的密碼] mysql -uroot -p$(awk '/temporary password/{print $NF}' /var/log/mysqld.log) 修改資料庫密碼 mysql> ALTER USER 'root'@'localhost' IDENTIFIED BY 'Bgx123.com'; mysql> exit
匯入原先的資料(三臺機器都要操作)
mysql -uroot -pBgx123.com < /tmp/db-all.sql#匯入原有的資料庫即可
然後重啟mysql
systemctl restart mysqld
增加使用者
db01主庫的操作
[root@db01 ~]# mysql -uroot -pBgx123.com mysql> grant all on *.* to 'all'@'%' identified by 'Bgx123.com';#這個是配置遠端連線規則 mysql> grant replication slave, replication clienton *.* to 'rep'@'172.16.1.%' identified by 'Rep123.com';#授權, 允許能夠遠端連線的主機(replicaiton) mysql> flush privileges;
在 master 上進行授權
在所有 Mysql進行授權
擁有管理許可權的使用者可在本地網路中有其他節點上遠端訪問。 mha為manager管理使用者
mysql> grant all on *.* to 'mha'@'172.16.%.%' identified by 'Bgx123.com';#所有資料庫都要進行授權 mysql> flush privileges; #mysql 新設定使用者或更改密碼後需用flush privileges重新整理MySQL的系統許可權相關表,否則會出現拒絕訪問
安裝MHA軟體
(在三個節點上都裝mha的node軟體)
在db03(manager監控端)安裝manager
[root@db01 ~]# ll -rw-r--r--1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm [root@db02 ~]# ll -rw-r--r--1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm [root@db03 ~]# ll -rw-r--r--1 root root 87119 Oct 24 20:11 mha4mysql-manager-0.56-0.el6.noarch.rpm -rw-r--r--1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
首先要確保yum源有base源和epel源而且可以上網
因為mha安裝會安裝依賴
[root@db02 ~]# ll /etc/yum.repos.d/ -rw-r--r-- 1 root root 2523 Sep4 17:06 CentOS-Base.repo -rw-r--r-- 1 root root664 Sep4 17:06 epel.repo
然後直接使用yum install 安裝
db03 manager node都要安裝 其他兩臺只安裝node
[root@db01 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y [root@db02 ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm [root@db03 ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm [root@db03 ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm
配置manager
mha配置檔案內容
[root@db03 ~]# mkdir /etc/mha_master/ [root@db03 ~]# cat /etc/mha_master/mha.cnf [server default] user=mha password=Bgx123.com manager_workdir=/etc/mha_master/app1 manager_log=/etc/mha_master/manager.log remote_workdir=/mydata/mha_master/app1 ssh_user=root repl_user=rep repl_password=Rep123.com ping_interval=1 [server1] hostname=172.16.1.51 port=3306 candidate_master=1 [server2] hostname=172.16.1.52 port=3306 candidate_master=1 #[server3] #hostname=172.16.1.53 #port=3306 #candidate_master=1
配置三臺機器的ssh互信(三臺都要操作)在配置MHA會要求三臺資料庫無密碼通訊
ssh-keygen -t rsa ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] ssh-copy-id -i /root/.ssh/id_rsa.pub [email protected] #測試是否成功 ssh 172.16.1.52不用輸入密碼就證明成功
指向Master 只在db02 db03操作
在兩個salve節點(從庫)上執行,只讀限制(防止意外被寫資料,很重要)
mysql> set global read_only=1; mysql> change master to -> master_host='172.16.1.51', -> master_user='rep', -> master_password='Rep123.com'; mysql> start slave; mysql> show slave status\G; #檢視slave IO和slave sql是否都正常 Yes就是正常的 Slave_IO_Running: Yes Slave_SQL_Running: Yes
測試配置
測試連通性
[root@db03 ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf#最後一行如下圖即為成功

確認上一步連通性沒問題後開始下一步檢查
檢查管理的MySQL複製叢集的連線配置引數是否OK
[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
底部顯示OK即為正常
配置VIP漂移
配置Keepalived
使用keepalived做VIP轉移
keepalived只在 db01 db02上安裝
[root@db01 ~]# yum install keepalived -y [root@db02 ~]# yum install keepalived -y
keepalived db01的配置檔案內容
[root@db01 ~]# cat /etc/keepalived/keepalived.conf global_defs { router_id db01 } vrrp_instance VI_1 { state MASTER interface eth1 virtual_router_id 50 priority 150 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.66/24 dev eth1 } }
啟動keepalived
systemctl start keepalived.service
keepalived db02的配置檔案內容
[root@db02 ~]# cat /etc/keepalived/keepalived.conf global_defs { router_id db02 } vrrp_instance VI_1 { state BACKUP interface eth1 virtual_router_id 50 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 172.16.1.66/24 dev eth1 } }
配置完不要忘記啟動
systemctl start keepalived.service
配置指令碼內容
寫入指令碼內容(我們使用的yum安裝 沒有自帶的指令碼 所以自己寫)見檔案包內
[root@db03 ~]# cat /usr/local/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 = '172.16.1.66'; my $ssh_start_vip = "systemctl start keepalived"; my $ssh_stop_vip = "systemctl stop keepalived"; 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"; &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 \"`; } # 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"; }
給指令碼增加執行許可權不然會報錯
[root@db03 ~]# chmod +x /usr/local/bin/master_ip_failover
在db03的配置檔案內加入一行(在原有內容的基礎上增加)
[root@db03 ~]# vim /etc/mha_master/mha.cnf master_ip_failover_script= /usr/local/bin/master_ip_failover
測試連通性
[root@db03 ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf
測試配置
[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
啟動mha (在db03上執行)
nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log & [1] 13530#這個號碼每次都會不一樣 [root@db03 ~]# masterha_check_status -conf=/etc/mha_master/mha.cnf mha (pid:13530) is running(0:PING_OK), master:172.16.1.51
上面的資訊中“mha (pid:13530) is running(0:PING_OK)”表示MHA服務執行OK,否則, 則會顯示為類似“mha is stopped(1:NOT_RUNNING).”
如果,我們想要停止 MHA ,則需要使用 stop 命令: [root@manager ~]# masterha_stop -conf=/etc/mha_master/mha.cnf
測試 MHA 故障轉移
先在db03開啟日誌
[root@db03 ~]# tail -f /etc/mha_master/manager.log
主庫 db01 關閉 mariadb 服務,模擬主節點資料崩潰
[root@db01 ~]# systemctl stop mysqld
轉移後的恢復
重新啟動主庫後
db01的操作(不要忘記重啟)
[root@db01 ~]# systemctl start mysqld [root@db01 ~]# systemctl start keepalived.service
在從庫上執行以下命令(重新設定從庫)
mysql> stop slave; mysql> reset slave; mysql> CHANGE MASTER TO MASTER_HOST=' 172.16.1.51', MASTER_USER='rep', MASTER_PASSWORD=' Rep123.com', MASTER_PORT=3306, MASTER_LOG_FILE='master-log.000005', MASTER_LOG_POS=154; mysql> start slave; mysql> show slave status\G;
db03的操作 (重新啟動mha之前一定要刪除這個目錄下的檔案 不然下次轉移報錯)
[root@db03 ~]# rm -f/etc/mha_master/app1/*
檢查
[root@db03 ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf
重新啟動
nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &