1. 程式人生 > >MySQL 高可用叢集架構 MHA 詳解

MySQL 高可用叢集架構 MHA 詳解

MHA(Master HighAvailability)目前在MySQL高可用方面是一個相對成熟的解決方案,它由日本DeNA公司youshimaton(現就職於Facebook公司)開發,是一套優秀的作為MySQL高可用性環境下故障切換和主從提升的高可用軟體。在MySQL故障切換過程中,MHA能做到在0~30秒之內自動完成資料庫的故障切換操作,並且在進行故障切換的過程中,MHA能在最大程度上保證資料的一致性,以達到真正意義上的高可用。

MHA裡有兩個角色一個是MHA Node(資料節點)另一個是MHA Manager(管理節點)

MHA Manager可以單獨部署在一臺獨立的機器上管理多個master-slave叢集,也可以部署在一臺slave節點上。MHA Node執行在每臺MySQL伺服器上,MHA Manager會定時探測叢集中的master節點,當master出現故障時,它可以自動將最新資料的slave提升為新的master,然後將所有其他的slave重新指向新的master。整個故障轉移過程對應用程式完全透明。

wKiom1i7xMCiMXPOAAEr-pBCQqs179.png

在MHA自動故障切換過程中,MHA試圖從宕機的主伺服器上儲存二進位制日誌,最大程度的保證資料的不丟失,但這並不總是可行的。例如,如果主伺服器硬體故障或無法通過ssh訪問,MHA沒法儲存二進位制日誌,只進行故障轉移而丟失了最新的資料。使用MySQL 5.5的半同步複製,可以大大降低資料丟失的風險。MHA可以與半同步複製結合起來。如果只有一個slave已經收到了最新的二進位制日誌,MHA可以將最新的二進位制日誌應用於其他所有的slave伺服器上,因此可以保證所有節點的資料一致性。

注:從MySQL5.5開始,MySQL以外掛的形式支援半同步複製。如何理解半同步呢?首先我們來看看非同步,全同步的概念:

非同步複製(Asynchronous replication

MySQL預設的複製即是非同步的,主庫在執行完客戶端提交的事務後會立即將結果返給給客戶端,並不關心從庫是否已經接收並處理,這樣就會有一個問題,主如果crash掉了,此時主上已經提交的事務可能並沒有傳到從上,如果此時,強行將從提升為主,可能導致新主上的資料不完整。

全同步複製(Fully synchronous replication

指當主庫執行完一個事務,所有的從庫都執行了該事務才返回給客戶端。因為需要等待所有從庫執行完該事務才能返回,所以全同步複製的效能必然會受到嚴重的影響。

半同步複製(Semisynchronous replication

介於非同步複製和全同步複製之間,主庫在執行完客戶端提交的事務後不是立刻返回給客戶端,而是等待至少一個從庫接收到並寫到relay log中才返回給客戶端。相對於非同步複製,半同步複製提高了資料的安全性,同時它也造成了一定程度的延遲,這個延遲最少是一個TCP/IP往返的時間。所以,半同步複製最好在低延時的網路中使用。

下面來看看半同步複製的原理圖:

wKioL1i7xPuytZlPAAJ4iO_x_dg848.png

總結:非同步與半同步異同

預設情況下MySQL的複製是非同步的,Master上所有的更新操作寫入Binlog之後並不確保所有的更新都被複制到Slave之上。非同步操作雖然效率高,但是在Master/Slave出現問題的時候,存在很高資料不同步的風險,甚至可能丟失資料。  MySQL5.5引入半同步複製功能的目的是為了保證在master出問題的時候,至少有一臺Slave的資料是完整的。在超時的情況下也可以臨時轉入非同步複製,保障業務的正常使用,直到一臺salve追趕上之後,繼續切換到半同步模式。

工作原理:

相較於其它HA軟體,MHA的目的在於維持MySQL Replication中Master庫的高可用性,其最大特點是可以修復多個Slave之間的差異日誌,最終使所有Slave保持資料一致,然後從中選擇一個充當新的Master,並將其它Slave指向它。

-從宕機崩潰的master儲存二進位制日誌事件(binlogevents)。

-識別含有最新更新的slave。

-應用差異的中繼日誌(relay log)到其它slave。

-應用從master儲存的二進位制日誌事件(binlogevents)。

-提升一個slave為新master。

-使其它的slave連線新的master進行復制。

目前MHA主要支援一主多從的架構,要搭建MHA,要求一個複製叢集中必須最少有三臺資料庫伺服器,一主二從,即一臺充當master,一臺充當備用master,另外一臺充當從庫,因為至少需要三臺伺服器。

部署環境如下:

角色 Ip 主機名 os
master 192.168.137.134 master CentOS 6.5 x86_64
Candidate 192.168.137.130 Candidate
slave+manage 192.168.137.146 slave

其中master對外提供寫服務,Candidate為備選master,管理節點放在純slave機器上。master一旦宕機,Candidate提升為主庫

一、基礎環境準備

1、在3臺機器上配置epel源

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo

rpm -ivh http://dl.Fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm

2、建立ssh無互動登入環境

[[email protected] ~]#ssh-keygen -t rsa -P ''        

chmod 600 .ssh/*

cat .ssh/id_rsa.pub >.ssh/authorized_keys

scp -p  .ssh/id_rsa .ssh/authorized_keys 192.168.137.130:/root/.ssh

scp -p  .ssh/id_rsa .ssh/authorized_keys 192.168.137.146:/root/.ssh

二、配置mysql半同步複製

注意:mysql主從複製操作此處不做演示

master授權:

grant replication slave,replication client on *.* to 'repl'@'192.168.137.%' identified by '123456';

grant all on *.* to 'mhauser'@'192.168.137.%' identified by '123456';

Candidate授權:

grant replication slave,replication client on *.* to 'repl'@'192.168.137.%' identified by '123456';

grant all on *.* to 'mhauser'@'192.168.137.%' identified by '123456';

slave授權

grant all on *.* to 'mhauser'@'192.168.137.%' identified by '123456';

如果用mysql預設的非同步模式,當主庫硬體損壞宕機造成的資料丟失,因此在配置MHA的同時建議配置成MySQL的半同步複製。

注:mysql半同步外掛是由谷歌提供,具體位置/usr/local/mysql/lib/plugin/下,一個是master用的semisync_master.so,一個是slave用的semisync_slave.so,

mysql> show variables like '%plugin_dir%';

+---------------+------------------------------+

| Variable_name | Value                        |

+---------------+------------------------------+

| plugin_dir    | /usr/local/mysql/lib/plugin/ |

+---------------+------------------------------+

1、分別在主從節點上安裝相關的外掛(master,Candidate,slave)

在MySQL上安裝外掛需要資料庫支援動態載入。檢查是否支援,用如下檢測:

mysql> show variables like '%have_dynamic_loading%';

+----------------------+-------+

| Variable_name        | Value |

+----------------------+-------+

| have_dynamic_loading | YES  

所有mysql資料庫伺服器,安裝半同步外掛(semisync_master.so,semisync_slave.so)

mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';

mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

檢查Plugin是否已正確安裝: mysql> show plugins; 或 mysql> select * from information_schema.plugins;

檢視半同步相關資訊

mysql> show variables like '%rpl_semi_sync%';

rpl_semi_sync_master_enabled       | OFF   |

| 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        | OFF   |

| rpl_semi_sync_slave_trace_level    | 32 

上圖可以看到半同複製外掛已經安裝,只是還沒有啟用,所以是OFF

2、修改my.cnf檔案,配置主從同步:

注:若主MYSQL伺服器已經存在,只是後期才搭建從MYSQL伺服器,在置配資料同步前應先將主MYSQL伺服器的要同步的資料庫拷貝到從MYSQL伺服器上(如先在主MYSQL上備份資料庫,再用備份在從MYSQL伺服器上恢復)

master mysql主機:

server-id = 1 log-bin=mysql-bin binlog_format=mixed

log-bin-index=mysql-bin.index

rpl_semi_sync_master_enabled=1

rpl_semi_sync_master_timeout=10000

rpl_semi_sync_slave_enabled=1

relay_log_purge=0

relay-log= relay-bin

relay-log-index = relay-bin.index

注:

rpl_semi_sync_master_enabled=1  1表是啟用,0表示關閉

rpl_semi_sync_master_timeout=10000:毫秒單位,該引數主伺服器等待確認訊息10秒後,不再等待,變為非同步方式。

Candidate 主機:

server-id = 2 log-bin=mysql-bin binlog_format=mixed

log-bin-index=mysql-bin.index

relay_log_purge=0

relay-log= relay-bin

relay-log-index = slave-relay-bin.index

rpl_semi_sync_master_enabled=1

rpl_semi_sync_master_timeout=10000

rpl_semi_sync_slave_enabled=1

注:relay_log_purge=0,禁止 SQL 執行緒在執行完一個 relay log 後自動將其刪除,對於MHA場景下,對於某些滯後從庫的恢復依賴於其他從庫的relaylog,因此採取禁用自動刪除功能

Slave主機:

Server-id = 3

log-bin = mysql-bin

relay-log = relay-bin

relay-log-index = slave-relay-bin.index read_only = 1

rpl_semi_sync_slave_enabled = 1

檢視半同步相關資訊

mysql> show variables like '%rpl_semi_sync%';

檢視半同步狀態:

mysql> show status like '%rpl_semi_sync%';

| Rpl_semi_sync_master_clients               | 2     |

重點關注的引數:

rpl_semi_sync_master_status :顯示主服務是非同步複製模式還是半同步複製模式 

rpl_semi_sync_master_clients :顯示有多少個從伺服器配置為半同步複製模式 

rpl_semi_sync_master_yes_tx :顯示從伺服器確認成功提交的數量 

rpl_semi_sync_master_no_tx :顯示從伺服器確認不成功提交的數量 

rpl_semi_sync_master_tx_avg_wait_time :事務因開啟 semi_sync ,平均需要額外等待的時間 

rpl_semi_sync_master_net_avg_wait_time :事務進入等待佇列後,到網路平均等待時間 

三、配置mysql-mha

  1. 所有mysql節點安裝 

    rpm -ivh perl-DBD-MySQL-4.013-3.el6.i686.rpm  [yum -y install perl-DBD-MySQL]

    rpm -ivh mha4mysql-node-0.56-0.el6.noarch.rpm

2. manage需安裝依賴的perl包  

    rpm -ivh perl-Config-Tiny-2.12-7.1.el6.noarch.rpm

    rpm -ivh perl-DBD-MySQL-4.013-3.el6.i686.rpm  [yum -y install perl-DBD-MySQL]

    rpm -ivh compat-db43-4.3.29-15.el6.x86_64.rpm

    rpm -ivh perl-Mail-Sender-0.8.16-3.el6.noarch.rpm

    rpm -ivh perl-Parallel-ForkManager-0.7.9-1.el6.noarch.rpm

    rpm -ivh perl-TimeDate-1.16-11.1.el6.noarch.rpm

    rpm -ivh perl-MIME-Types-1.28-2.el6.noarch.rpm

    rpm -ivh perl-MailTools-2.04-4.el6.noarch.rpm

    rpm -ivh perl-Email-Date-Format-1.002-5.el6.noarch.rpm

    rpm -ivh perl-Params-Validate-0.92-3.el6.x86_64.rpm

    rpm -ivh perl-Params-Validate-0.92-3.el6.x86_64.rpm

    rpm -ivh perl-MIME-Lite-3.027-2.el6.noarch.rpm

    rpm -ivh perl-Mail-Sendmail-0.79-12.el6.noarch.rpm

    rpm -ivh perl-Log-Dispatch-2.27-1.el6.noarch.rpm

    yum install -y perl-Time-HiRes-1.9721-144.el6.x86_64

    rpm -ivh mha4mysql-manager-0.56-0.el6.noarch.rpm

3. 配置mha

配置檔案位於管理節點,通常包括每一個mysql server的主機名,mysql使用者名稱,密碼,工作目錄等等。

mkdir /etc/masterha/

vim /etc/masterha/app1.cnf

[server default]

user=mhauser

password=123456

manager_workdir=/data/masterha/app1 

manager_log=/data/masterha/app1/manager.log

remote_workdir=/data/masterha/app1

ssh_user=root

repl_user=repl

repl_password=123456

ping_interval=1

[server1]

hostname=192.168.137.134

port=3306

master_binlog_dir=/usr/local/mysql/data

candidate_master=1

[server2]

hostname=192.168.137.130

port=3306

master_binlog_dir=/usr/local/mysql/data

candidate_master=1

[server3]

hostname=192.168.137.146

port=3306

master_binlog_dir=/usr/local/mysql/data

no_master=1

配關配置項的解釋

manager_workdir=/masterha/app1//設定manager的工作目錄

manager_log=/masterha/app1/manager.log//設定manager的日誌

user=manager//設定監控使用者manager

password=123456  //監控使用者manager的密碼

ssh_user=root  //ssh連線使用者

repl_user=mharep  //主從複製使用者

repl_password=123.abc//主從複製使用者密碼

ping_interval=1  //設定監控主庫,傳送ping包的時間間隔,預設是3秒,嘗試三次沒有迴應的時候自動進行failover

master_binlog_dir=/usr/local/mysql/data  //設定master 儲存binlog的位置,以便MHA可以找到master的日誌,我這裡的也就是mysql的資料目錄

candidate_master=1//設定為候選master,如果設定該引數以後,發生主從切換以後將會將此從庫提升為主庫。

檢測各節點間ssh互信通訊配置是否ok

    masterha_check_ssh --conf=/etc/masterha/app1.cnf

    結果:All SSH connection tests passed successfully.

檢測各節點間主從複製是否ok

    masterha_check_repl --conf=/etc/masterha/app1.cnf

    結果:MySQL Replication Health is OK.

在驗證時,若遇到這個錯誤:Can't exec "mysqlbinlog" ......

解決方法是在所有伺服器上執行:

    ln -s /usr/local/mysql/bin/* /usr/local/bin/

啟動manager:

nohup /usr/bin/masterha_manager --conf=/etc/masterha/app1.cnf  --remove_dead_master_conf --ignore_last_failover > /etc/masterha/manager.log 2>&1 &

--remove_dead_master_conf 為主從切換後,老的主庫IP將會從配置檔案中移除

--ignore_last_failover 忽略生成的切換完成檔案,若不忽略,則8小時內無法再次切換

--ignore_fail_on_start

##當有slave 節點宕掉時,MHA預設是啟動不了的,加上此引數即使有節點宕掉也能啟動MHA,

關閉MHA:

masterha_stop  --conf=/etc/masterha/app1.cnf

檢視MHA狀態:

masterha_check_status --conf=/etc/masterha/app1.cnf

app1 (pid:45128) is running(0:PING_OK), master:192.168.137.134

4.模擬故障轉移

  1. 停掉master,

    /etc/init.d/mysqld stop

  2. 檢視 MHA 日誌  /data/masterha/app1/manager.log

----- Failover Report -----

app1: MySQL Master failover 192.168.137.134(192.168.137.134:3306) to 192.168.137.1

30(192.168.137.130:3306) succeeded

Master 192.168.137.134(192.168.137.134:3306) is down!

Check MHA Manager logs at zifuji:/data/masterha/app1/manager.log for details.

Started automated(non-interactive) failover.

The latest slave 192.168.137.130(192.168.137.130:3306) has all relay logs for reco

very.

Selected 192.168.137.130(192.168.137.130:3306) as a new master.

192.168.137.130(192.168.137.130:3306): OK: Applying all logs succeeded.

192.168.137.146(192.168.137.146:3306): This host has the latest relay log events.

Generating relay diff files from the latest slave succeeded.

192.168.137.146(192.168.137.146:3306): OK: Applying all logs succeeded. Slave star

ted, replicating from 192.168.137.130(192.168.137.130:3306)

192.168.137.130(192.168.137.130:3306): Resetting slave info succeeded.

Master failover to 192.168.137.130(192.168.137.130:3306) completed successfully.

3.  檢視slave複製狀態

*************************** 1. row ***************************

               Slave_IO_State: Waiting for master to send event

                  Master_Host: 192.168.137.130

                  Master_User: repl

                  Master_Port: 3306

                Connect_Retry: 60

              Master_Log_File: mysql-bin.000003

linux