2016年7月21日 星期四

架設 HA 高可用性:MySQL DRBD + Heartbeat - 兩台式架構 HA (Master/Slave)

在 MySQL HA 架構,企業中使用最頻繁的就是 DRBD + Heartbeat,其原因沒有別的,就是最省錢;只需要兩台 Database Server,並且使用 Master / Slave Fail-over 進行備援,若是 Master 掛掉,只需要在短短的幾秒內即可讓 Slave 升上 Master 上線服務。

 

MySQL HA 有幾種選擇 MHA、MMM、Keepalived、Heartbeat、Pacemaker ..

使用兩台式的 Master / Slave 的缺點上就是沒有第三台 Monitor Server 協助判定主機 Active / Dead以及切換,所以在技術上如果沒有處理好的話就會造成 split-brain 的狀況,這樣就必須要人為介入處理

 

DRBD + Heartbeat 官方也提供了 split-brain 的自動復原功能 Configure-split-brain-behavior

 

在這篇是採用 DRBD + Heartbeat 做 LAB 使用,架構如下:

MySQL DRBD + Heartbeat (two host)



採用兩台 Database Server,平時僅有 Master 運作,而 Slave 處於 stand by 的狀態,只有發生狀況才會替補上。

 

Client 端都是使用 VIP 在進行連線,Master / Slave 之間使用 heartbeat 心跳偵測彼此是否 Active / Dead,當 Master dead 狀態成立,heartbeat 會將 Slave 升級為 Master、掛載 Disk 資源池、啟動 MySQLd,整個流程的 down time 時間可以自己依照網路環境調整,若對你的內網很有信心,整個 MySQL 的 downtime 可以不超過 5 秒。

 

建立高可用性(HA) 的 MySQL - DRBD + Heartbeat

  • mysql-node1:192.168.50.20

  • mysql-node2:192.168.50.21

  • Virtual IP:192.168.50.22

  • meta disk:/dev/sdb1


 

**** 以下設定請在 mysql-node1、mysql-node2 同步作業 ****

 

建立 DRBD

Step.1 安裝 EL repo、drbd84
$ rpm -ivh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm 
$ yum install drbd84-utils kmod-drbd84 --enablerepo=el

 

Step.2 檢查 kernel 版本是否支援對應的 DRBD 版本,並且載入 kernel drbd module,若沒有載入你的 drbd 是無法使用的

此篇是採用 drbd84 所支援的 kernel 最少要是 2.6.32-573.xx,在這之前的 kernel 請使用 drbd83
$ uname -r 
2.6.32-642.1.1.el6.x86_64

$ modprobe drbd
#如果出現"FATAL: Module drbd not found."代表你的 kernel 並不支援 drbd84,請升級你的 kernel

 

Step.3 設定 hosts、hostname,DRBD 的設定會需要 hostname 和 hosts

 
$ vim /etc/hosts 
192.168.50.20 mysql-node1
192.168.50.21 mysql-node2

$ vim /etc/sysconfig/network
HOSTNAME=mysql-node1

#HOSTNAME請設定mysql-node1、mysql-node2的主機名稱

 

Step.4 設定 drbd 的 global_common.conf 全局設定
$ vim /etc/drbd.d/global_common.conf 

global {
usage-count no; # 是否提供DRBD進行分析 http://usage.drbd.org/
}
common {
net {
protocol C; # A 異地複製。Master寫入本機硬碟完畢並發送網路同步後即判定同步完成,Slave可能會有未寫入完全的風險。
} # B Memory複製。Master寫入本機硬碟完畢並發送給Slave記憶體空間即判定同步完成,若是出現異常則可能遺失最近幾次的資料。
} # C 同步複製。Master寫入本機硬碟完畢並且Slave也寫入硬碟完畢判定同步完成。

 

Step.5 設定 drbd 的 meta data 資源池,
$ vim /etc/drbd.d/meta.res 

#建立資源池
resource meta {
disk {
resync-rate 1000M; # 同步速度, 依照你網卡的速度而定
}
device /dev/drbd0; # drbd 使用的 device 名稱
disk /dev/sdb1; # 實際切割出來的磁區,必須是 block device
meta-disk internal; # 此外還有 external
on mysql-node1 { # 和 hostname 相同
address 192.168.50.20:7789;
}
on mysql-node2 {
address 192.168.50.21:7789;
}
}

如上的設定方式是 mysql-node1、mysqlnode2 具有相同的 /dev/sdb1、所以我寫在 resource meta 變數內而不是寫在 node 內。

 

Step.6 初始化 metadata
$ drbdadm create-md meta 

initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.

 

Step.7 兩邊都啟動 drbd
$ drbdadm up meta

 

Step.8 查看 drbd 狀態
$ cat /proc/drbd 

version: 8.4.7-1 (api:1/proto:86-101)
GIT-hash: 3a6a769340ef9db1ba2792c642c251790795db49 build by mockbuild@Build64R6, 2016-01-12 13:27:11
0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----
ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:104854364

因為還沒有決定要以哪邊的資料為主,所以 ds:Inconsistent,兩邊都是 Secondary

 

Step.9 在要決定是 Master 的 mysql-node1 執行 primary 使他升上 Master
# in mysql-node1 
$ drbdadm primary --force r1

$ cat /proc/drbd

# mysql-node1被升上Primary,並且ds為UpToDate,正同步到mysql-node2(Slave)
version: 8.4.7-1 (api:1/proto:86-101)
GIT-hash: 3a6a769340ef9db1ba2792c642c251790795db49 build by mockbuild@Build64R6, 2016-01-12 13:27:11
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
ns:0 nr:0 dw:0 dr:0 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:104854364
[================>...] sync'ed: 89.0% (8821390/1024000)M
finish: 0:00:27 speed: 33,052 (32,148) K/sec

 

Step.10 同步完成 ds 狀態為 UpToDate/UpToDate。
$ cat /proc/drbd 

version: 8.4.7-1 (api:1/proto:86-101)
GIT-hash: 3a6a769340ef93b1ba2792c6461250790795db49 build by mockbuild@Build64R6, 2016-01-12 13
:27:11
0: cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:100068956 dw:100068956 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

 

Step.11 先格式化 drbd 磁區,然後準備資料
$ mkfs.ext4 /dev/drbd0

 

Step.12 將 MySQL data 指定到要 mount 的 metadata
$ mkdir -p /drbd/mysql 
$ vim /etc/my.cnf
datadir=/drbd/mysql

 

Step.13 在 mysql-node1 嘗試 mount metadata,因為在 drbd 啟動時僅有 Master 有權限可以 mount metadata
$ mount /dev/drbd0 /drbd/mysql 
$ service mysqld start

測試 create data 檢查是否可以寫入,如果你檢測 cat /proc/drbd 可以看到 dw 一直在寫入。

 

DRBD 測試

你可以在 mysql-node1、mysql-node2 之間切換 Primary/Secondary 並且寫入一些資料,確認同步OK
$ drbdadm primary meta      # 升級為primary 
$ drbdadm secondary meta # 降級為secondary

若是你只用 DRBD 的話就只能手動切換,這樣就沒有意義了,所以要搭配像是 Heartbeat 或是 Keepalive 這類型的東西來 Failover。

 

建立 Heartbeat

Step.1 直接下載 heartbeat
$ yum install heartbeat

 

Step.2 ha.cf 主要設定檔
$ vim /etc/ha.d/ha.cf 

autojoin none
debugfile /var/log/ha-debug # debug log
logfile /var/log/ha-log # log
logfacility local0
keepalive 2 # 每隔2秒確認一次對方存活狀態
deadtime 10 # 當出現dead癥兆,10秒後確認已死機
warntime 4 # 當出現dead癥兆,4秒後警告
initdead 60 # 伺服器重開後等待init的啟動時間為60秒後才開始heartbeat
udpport 694 # heartbeat互相監控的port
ucast eth0 192.168.50.20 # 填寫對方的IP,使用eth0/UDP單播連接,發送heartbeat訊息給對方,此外還有廣播的方式,但不建議使用。
auto_failback off # 若是master恢復後是否將primary歸還,建議off。
node mysql-node1 # node 節點,與hostname相同
node mysql-node2
ping 192.168.50.254 # 第二個IP,作為網路正不正常的另一個依據。
respawn hacluster /usr/lib64/heartbeat/ipfail # heartbeat ip fail的工具套件,背景常駐
respawn hacluster /usr/lib64/heartbeat/dopd # heartbeat 升降Master/Slave的工具,背景常駐
apiauth dopd gid=haclient uid=hacluster # heartbeat 所使用的權限

 

Step.3 heartbeat 連線所使用的認證密碼檔,使用目前安全性尚OK的 sha1,權限必須為 600,並且加入 heartbeat 的都必須擁有此 authkeys
$ (echo -ne "auth 1\n1 sha1 "; echo $RANDOM | openssl sha1 | awk '{print $2}') > /etc/ha.d/authkeys 
$ chmod 600 /etc/ha.d/authkeys

 

Step.4 設定 haresources,當發生故障異常時,heartbeat 要幫你做的事情就在 haresources 進行設定
mysql-node1 IPaddr::192.168.50.22/32/eth0:1 drbddisk::meta Filesystem::/dev/drbd0::/drbd/mysqldata::ext4 mysqld


  • mysql-node1:預設啟動時mysql-node1為Master

  • IPaddr:VIP 設定,IP:192.168.50.22、netmask:255.255.255.0、interface:eth0:1,如果沒有設定netmask/interface將會自動幫你掛載在第一張網卡,如果你希望啟動另一張網卡就必須指定 netmask/interface


 

當 mysql-node1、mysql-node2 都 ready 好之後就可以啟動服務
$ chkconfig drbd on  
$ chkconfig heartbeat on
$ chkconfig mysqld off # 預設開機不啟動,讓heartbeat來進行啟動。

 

 

測試:

case.1 將master中斷時,slave偵測到並升上primary
# 警告mysql-node1已死 
heartbeat: [19973]: WARN: node mysql-node1: is dead

# 由於mysql-node1已死,所以mysql-node1已經放棄resources
heartbeat: [19973]: info: Dead node mysql-node1 gave up resources.

# 最後確認mysql-node1死亡
ipfail: [20000]: info: Status update: Node mysql-node1 now has status dead

# mysql-node1 eth0 死亡
heartbeat: [19973]: info: Link mysql-node1:eth0 dead.

# ipfail 偵測到 slave 還活著!!!
ipfail: [20000]: info: NS: We are still alive!

# ipfail 進行狀態更新
ipfail: [20000]: info: Link Status update: Link mysql-node1:eth0 now has status dead
ipfail: [20000]: info: Asking other side for ping node count.
ipfail: [20000]: info: Checking remote count of ping nodes.

 

case.2 slave復原,master 偵測到復原通知,僅更改slave狀態由dead轉avtive
# mysql-node1 偵測到上線 
heartbeat: [19973]: info: Link mysql-node1:eth0 up.

# mysql-node1 更新狀態初始化
heartbeat: [19973]: info: Status update for node mysql-node1 : status init

# ipfail 又出場更新狀態了
ipfail: [20000]: info: Link Status update: Link mysql-node1:eth0 now has status up
heartbeat: [19973]: info: all clients are now paused
ipfail: [20000]: info: Status update: Node mysql-node1 now has status active
heartbeat: [19973]: info: remote resource transition completed.
heartbeat: [19973]: info: all clients are now resumed
ipfail: [20000]: info: Asking other side for ping node count.
ipfail: [20000]: info: No giveup timer to abort.

 

當然在這中間還處理了 haresources 裡的動作,在這裡指擷取部分狀態的判定 log

 

 

 

 

 

架設技巧:

如果你的 DRBD 同步線路為獨立網卡,若是不想浪費資源可以直接設定為網卡最大傳輸速率,在 Linux 可以這樣看網卡速率
$ dmesg |grep eth0 

dmesg | grep eth0 | grep interface
bond0: Enslaving eth0 as a backup interface with a down link
bond0: link status definitely up for interface eth0, 1000 Mbps full duplex

 

Debug:

Q1:在啟動 heartbeat 服務時出現『Unable to find nic or netmask.』

Ans:這個訊息是 heartbeat 掛載 VIP 失敗,無法找到 netmask,如果沒設定 netmask 會預設抓你第一張網卡的 netmask,若是有誤就無法掛載上去,可以使用 ifconfig up 的方式測試是否可以成功掛上VIP。

 

 

 

參考資料:

DRBD Users Guide 8.4

Configure-split-brain-behavior

0000626: kmod-drbd84 do not build on CentOS 6.6 final 2.6.32-504.30.3.el6.x86_64

Add a secondary IP to Linux

 

Orignal From: 架設 HA 高可用性:MySQL DRBD + Heartbeat - 兩台式架構 HA (Master/Slave)

沒有留言:

張貼留言