1. 程式人生 > >MHA高可用 MHA+Keepalive

MHA高可用 MHA+Keepalive

MHA高可用

MHA簡介

MHA(Master High Availability)目前在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的內容

[[email protected] ~]# vi /etc/my.cnf   #使用vi開啟
[mysqld]  
server-id=51  
log-bin = master-log  
relay-log = relay-log  
skip_name_resolve  

db02的內容

[[email protected] ~]# 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的內容

[[email protected] ~]# 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主庫的操作

[[email protected] ~]# mysql -uroot -pBgx123.com
mysql> grant all on *.* to 'all'@'%' identified by 'Bgx123.com';   #這個是配置遠端連線規則
mysql> grant replication slave, replication client  on *.*
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

[[email protected] ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# ll
-rw-r--r--  1 root root 36326 Oct 24 20:11 mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# 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安裝會安裝依賴

[[email protected] ~]# ll /etc/yum.repos.d/
-rw-r--r-- 1 root root 2523 Sep  4 17:06 CentOS-Base.repo
-rw-r--r-- 1 root root  664 Sep  4 17:06 epel.repo

然後直接使用yum install 安裝 db03 manager node都要安裝 其他兩臺只安裝node

 [[email protected] ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm -y
[[email protected] ~]# yum install -y mha4mysql-node-0.56-0.el6.noarch.rpm
[[email protected] ~]# yum install mha4mysql-manager-0.56-0.el6.noarch.rpm
[[email protected] ~]# yum install mha4mysql-node-0.56-0.el6.noarch.rpm

配置manager

mha配置檔案內容

[[email protected] ~]# mkdir /etc/mha_master/
[[email protected] ~]# 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

測試配置

測試連通性

[[email protected] ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf  #最後一行如下圖即為成功

確認上一步連通性沒問題後開始下一步檢查 檢查管理的MySQL複製叢集的連線配置引數是否OK

[[email protected] ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf

底部顯示OK即為正常

配置VIP漂移

配置Keepalived

使用keepalived做VIP轉移 keepalived只在 db01 db02上安裝

[[email protected] ~]# yum install keepalived -y
[[email protected] ~]# yum install keepalived -y

keepalived db01的配置檔案內容

[[email protected] ~]# 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的配置檔案內容

[[email protected] ~]# 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安裝 沒有自帶的指令碼 所以自己寫)見檔案包內

[[email protected] ~]# 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 ([email protected]) {
            warn "Got Error: [email protected]\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 ([email protected]) {
            warn [email protected];
            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";
}

給指令碼增加執行許可權不然會報錯

[[email protected] ~]# chmod +x /usr/local/bin/master_ip_failover

在db03的配置檔案內加入一行(在原有內容的基礎上增加)

[[email protected] ~]# vim /etc/mha_master/mha.cnf
master_ip_failover_script= /usr/local/bin/master_ip_failover

測試連通性

[[email protected] ~]# masterha_check_ssh -conf=/etc/mha_master/mha.cnf

測試配置

[[email protected] ~]# 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  #這個號碼每次都會不一樣
[[email protected] ~]# 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 命令:
[[email protected] ~]# masterha_stop -conf=/etc/mha_master/mha.cnf

測試 MHA 故障轉移

先在db03開啟日誌

[[email protected] ~]# tail -f /etc/mha_master/manager.log

主庫 db01 關閉 mariadb 服務,模擬主節點資料崩潰

[[email protected] ~]# systemctl stop mysqld

轉移後的恢復

重新啟動主庫後 db01的操作(不要忘記重啟)

[[email protected] ~]# systemctl start mysqld
[[email protected] ~]# 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之前一定要刪除這個目錄下的檔案 不然下次轉移報錯)

[[email protected] ~]# rm -f  /etc/mha_master/app1/*

檢查

[[email protected] ~]# masterha_check_repl -conf=/etc/mha_master/mha.cnf

重新啟動

nohup masterha_manager -conf=/etc/mha_master/mha.cnf &> /etc/mha_master/manager.log &