DRBD+Heartbeat+Mysql 高可用實戰

實驗環境:Centos 6.7_64位php

服務器:node

Master節點:dm1 IP地址:10.0.0.61(eth0) 192.168.3.150(eth1,心跳) mysql

Slave節點:dm2  Ip地址:10.0.0.62(eth0) 192.168.3.160(eth1,心跳)linux

VIP地址:192.168.0.180ios


1、DRBD環境搭建nginx

DRBD(DistributedReplicatedBlockDevice)是一個基於塊設備級別在遠程服務器直接同步和鏡像數據的軟件,用軟件實現的、無共享的、服務器之間鏡像塊設備內容的存儲複製解決方案。它能夠實如今網絡中兩臺服務器之間基於塊設備級別的實時鏡像或同步複製(兩臺服務器都寫入成功)/異步複製(本地服務器寫入成功),至關於網絡的RAID1,因爲是基於塊設備(磁盤,LVM邏輯卷),在文件系統的底層,因此數據複製要比cp命令更快,DRBD已經被MySQL官方寫入文檔手冊做爲推薦的高可用的方案之一。web

DRBD工做原理:算法

提供兩個大小相同的分區,在數據流的層次上構建一個磁盤鏡像,就如同raid1,因此又被稱爲分佈式raidsql

主從架構:primary/secondary
默認結構,兩節點的全部存儲屬性,內容皆相同;
同一時刻只能有一個節點上線(即從節點,讀寫皆不可),主節點接到數據後,將數據備份到磁盤,同時傳遞給從節點,並存放到磁盤中.此時文件系統可使用本地文件系統:ext2 ext3 xfs等shell

雙主模型:
同一時刻能夠有兩個節點同時工做,即組內節點皆上線;
節點必須爲集羣文件系統,如:GFS2;OCFS2(自己提供高可用功能)
必須支持分佈式文件鎖(內核支持),主節點寫入的時候,從節點就從文件鎖得知對方在寫入;
高可用集羣的底層文件信息通道(必須將DRBD作成集羣資源).

簡言之:
Master/Master模式:
一、文件系統必須爲集羣文件系統如:GFS2;OCFS2(自己提供高可用功能)
二、使用高可用環境
三、使用分佈式鎖DLM

Master/Slave模式:
一、可使用普通文件系統
二、能夠切換主從角色
三、若是須要爲高可用提供存儲空間,須要將DRBD做爲HA的一個資源
四、從節點不可讀、不可寫、不可掛載

由於drbd工做在內核,故須要用戶空間工具提供規則,因此它由用戶空間工具和內核模塊組成,就如同iptables和LVS同樣.drbd共有兩 部分組成:內核模塊和用戶空間的管理工具。其中drbd內核模塊代碼已經整合進Linux內核2.6.33之後的版本中,所以,若是您的內核版本高於此版 本的話,你只須要安裝管理工具便可;不然,您須要同時安裝內核模塊和管理工具兩個軟件包,而且此二者的版本號必定要保持對應。

不支持多個從,至少當前不支持

用戶空間工具:

告知內核哪一個分區是drbd設備

 drbdadm     /usr/local/drbd  /etc/drbd.d/

|__  drbdadm primary resource_name        升級爲主節點

|__  drbdadm secondary resource_name    降級爲備節點

drbdsetup

drbdmeta

查看drbd狀態,有兩種方法:

service  drbd  status

cat  /proc/drbd

工做模式:

DRBD有三種工做模式告知上層進程寫入完成:A異步(異步的傳輸),B半同步(同步到內存),C同步(同步到對方的磁盤上)
A模式:主節點接到數據,只保證發送到本地網卡的數據緩衝區(性能最好),即數據一旦寫入磁盤併發送到網絡中就認爲完成了寫入操做。
B模式:主節點接到數據,保證數據發送到從節點緩衝區,且存到了從節點的內核區,可是是否數據存儲到從節點的硬盤,則不清楚。即收到接收確認就認爲完成了寫入操做。
C模式:主節點接到數據,保證數據發送到從節點緩衝區,同時接到從節點存到從節點硬盤的信息(安全最高)。即收到寫入確認就認爲完成了寫入操做。

簡言之:
ProtocolA:異步,數據被送到TCP/IP協議緩衝區就宣佈複製完成
ProtocolB:半同步,也稱內存同步,數據發送到從節點的內存接收緩衝區
ProtocolC:同步,數據寫到對方的磁盤

如何解決故障後自動切換

利用高可用的底層信息通道(如HA的heartbeat或者corosync)+pacemaker進行資源監控,將drbd定義爲資源,且drbd資源有主從之分.

1. 添加附加庫:

官方網站:http://elrepo.org/tiki/tiki-index.php

如下測試針對Centos 6.7 版本:

a)import public key:

#rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org

b)安裝庫:

#rpm -Uvh http://www.elrepo.org/elrepo-release-6-6.el6.elrepo.noarch.rpm

2. 安裝DRBD:

DRBD官方網站:http://drbd.linbit.com/docs/install/

  # yum install drbd84 kmod-drbd84-y

3. 兩臺服務器上的分區/dev/sdb1做爲drbd的網絡mirror分區:

 格式化分區

# fdisk /dev/sdb

[root@dm1~]# fdisk -l /dev/sdb

Disk/dev/sdb: 10.7 GB, 10737418240 bytes

255heads, 63 sectors/track, 1305 cylinders

Units= cylinders of 16065 * 512 = 8225280 bytes

Sectorsize (logical/physical): 512 bytes / 512 bytes

I/Osize (minimum/optimal): 512 bytes / 512 bytes

Diskidentifier: 0xbe3466e3

   Device Boot      Start         End      Blocks  Id  System

/dev/sdb1               1         650    5221093+  83  Linux #存放數據

/dev/sdb2             651        1305    5261287+   5  Extended

/dev/sdb5             651        1305    5261256   83  Linux  #meta分區,存放drbd同步的狀態信息

注意:

1>、meta分區必定不能格式化創建文件系統(sdb5存放drbd同步的狀態信息)

2>、分好的分區不要進行掛載

3>、生產環境DRBD meta分區通常可設置爲1-2G,數據分區看需求給最大

4>、在生產環境中兩塊硬盤同樣大

# mkfs.ext4 /dev/sdb1  #只在主機上作

4.開始配置drbd:

# modprobe drbd

注意:不要設置echo'modprobe drbd' >>/etc/rc.loca開機自動加載drbd模塊,若是drbd服務是開機自啓動的,會先啓動drbd服務在加載drbd的順序,致使drbd啓動不了出現的問題.

主備節點兩端配置文件徹底一致

[root@dm1~]# vi /etc/d

dbus-1/        depmod.d/      dracut.conf    drbd.conf

default/       dhcp/          dracut.conf.d/ drbd.d/

[root@dm1 ~]# cat /etc/drbd.conf

# Youcan find an example in /usr/share/doc/drbd.../drbd.conf.example

 

include"drbd.d/global_common.conf";

include"drbd.d/*.res";

[root@dm1 ~]# vi /etc/drbd.d/mysql.res

#設定資源名稱爲: mysql_data

resource  mysql_data {

            protocol C;

            net {

                 cram-hmac-alg sha1;

                 shared-secret "abc";

            }

            on dm1 {

                 device    /dev/drbd1;

                 disk      /dev/sdb1;   #掛載drbd對應的系統分區

                 address   10.0.0.61:7788;

                 meta-disk /dev/sdb5 [0];

            }

            on dm2 {

                 device    /dev/drbd1;

                 disk      /dev/sdb1;

                 address   10.0.0.62:7788;

                 meta-disk /dev/sdb5 [0];

            }

}

5.初始化meta分區:

[root@dm1 ~]# drbdadm create-md mysql_data

initializing activity log

NOT initializing bitmap

Writing meta data...

New drbd meta data block successfully created.

Success

6. 啓動drbd:

[root@dm1 ~]# /etc/init.d/drbd start

[root@dm1 ~]# chkconfig drbd off

7.初始化設備同步(覆蓋備節點,保持數據一致):

[root@dm1 ~]# drbdadm -- --overwrite-data-of-peer primary mysql_data  #只在主服務器上操做

8. 掛載drbd分區到data數據目錄:

[root@dm1 ~]# df -h

Filesystem      Size  Used Avail Use% Mounted on

/dev/sda3        14G  1.5G  12G  12% /

tmpfs           238M     0 238M   0% /dev/shm

/dev/sda1       190M   52M 129M  29% /boot

[root@dm1 ~]# mkdir /data

[root@dm1 ~]# drbdadm primary all

[root@dm1 ~]# mount /dev/drbd1 /data

[root@dm1 ~]# df -h

Filesystem      Size  Used Avail Use% Mounted on

/dev/sda3        14G  1.5G  12G  12% /

tmpfs           238M     0 238M   0% /dev/shm

/dev/sda1       190M   52M 129M  29% /boot

/dev/drbd1      4.8G   10M 4.6G   1% /data

說明:/data目錄爲數據庫的數據目錄

9. 測試DRBD:

正常狀態

[root@dm1 ~]# cat /proc/drbd

version: 8.4.7-1 (api:1/proto:86-101)

GIT-hash: 3a6a769340ef93b1ba2792c6461250790795db49 build bymockbuild@Build64R6, 2016-01-12 13:27:11

 1: cs:SyncSourcero:Primary/Secondary ds:UpToDate/Inconsistent C r-----

    ns:4701184 nr:0 dw:0 dr:4701843al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:519912

        [=================>..]sync'ed: 90.2% (504/5096)M

        finish: 0:00:12 speed:42,268 (32,872) K/sec

[root@dm2 ~]# cat /proc/drbd

version: 8.4.7-1 (api:1/proto:86-101)

GIT-hash: 3a6a769340ef93b1ba2792c6461250790795db49 build bymockbuild@Build64R6, 2016-01-12 13:27:11

 1: cs:SyncTargetro:Secondary/Primary ds:Inconsistent/UpToDate C r-----

    ns:0 nr:309640 dw:309640 dr:0al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:4911456

        [>...................]sync'ed:  93.20% (4796/5096)M

        finish: 0:05:37 speed:14,552 (11,056) want: 21,240 K/sec

說明:dm1爲主節點,dm2爲備節點

模擬dm1宕機:

[root@dm1 ~]# umount /dev/drbd1

[root@dm1 ~]# drbdadm down all

[root@dm2 ~]# cat /proc/drbd     

version: 8.4.7-1 (api:1/proto:86-101)

GIT-hash: 3a6a769340ef93b1ba2792c6461250790795db49 build bymockbuild@Build64R6, 2016-01-12 13:27:11

 1: cs:WFConnectionro:Secondary/Unknown ds:UpToDate/DUnknown C r-----

   ns:0 nr:5221101 dw:5221101 dr:0al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

[root@dm2 ~]# mkdir /data

[root@dm2 ~]# drbdadmprimary all

[root@dm2 ~]# mount/dev/drbd1 /data

[root@dm2 ~]# df -h

Filesystem     Size  Used Avail Use% Mounted on

/dev/sda3       14G  1.5G   12G 12% /

tmpfs          238M     0  238M  0% /dev/shm

/dev/sda1      190M   52M  129M 29% /boot

/dev/drbd1     4.8G   10M  4.6G  1% /data

說明:dm1宕機後,dm2能夠升級爲主節點,可掛載drbd分區繼續使用


2、Heartbeat環境搭建

官方站點:http://linux-ha.org/wiki/Main_Page

heartbeat能夠資源(VIP地址及程序服務)從一臺有故障的服務器快速的轉移到另外一臺正常的服務器提供服務,heartbeat和keepalived類似,heartbeat能夠實現failover功能,但不能實現對後端的健康檢查

heartbeat和keepalived應用場景及區別:

不少網友說爲何不使用keepalived而使用長期不更新的heartbeat,下面說一下它們之間的應用場景及區別

一、對於web,db,負載均衡(lvs,haproxy,nginx)等,heartbeat和keepalived均可以實現

二、lvs最好和keepalived結合,由於keepalived最初就是爲lvs產生的,(heartbeat沒有對RS的健康檢查功能,heartbeat能夠經過ldircetord來進行健康檢查的功能)

三、mysql雙主多從,NFS/MFS存儲,他們的特色是須要數據同步,這樣的業務最好使用heartbeat,由於heartbeat有自帶的drbd腳本

總結:無數據同步的應用程序高可用可選擇keepalived,有數據同步的應用程序高可用可選擇heartbeat

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

Heartbeat具體的安裝配置:http://linuxzkq.blog.51cto.com/9379412/1771152

如下僅提供配置文件供參考:

vi authkeys #打開下面兩項:一共有三種認證方式供選擇,第一種是CRC循環冗餘校驗,第二種是SHA1哈希算法,第三種是MD3哈希算法,其中他們的密碼能夠任意設置,可是兩邊密碼必須保持一致。  

auth 3 

3 md5 Hello!

chmod 600 authkeys  #給認證文件受權爲600

[root@dm1 ha.d]# cat ha.cf

debugfile/var/log/ha-debug

logfile/var/log/ha-log

logfacility     local0

keepalive 2

deadtime 30

warntime 10

initdead 120

udpport 694

ucast eth1 192.168.3.160

auto_failback  off

node    dm1

node    dm2

ping 10.0.0.254

respawn hacluster  /usr/lib64/heartbeat/ipfail

[root@dm2 ha.d]# cat ha.cf

debugfile/var/log/ha-debug

logfile/var/log/ha-log

logfacility     local0

keepalive 2

deadtime 30

warntime 10

initdead 120

udpport 694

ucast eth1 192.168.3.150

auto_failback  off

node    dm1

node    dm2

ping 10.0.0.254

respawn  hacluster  /usr/lib64/heartbeat/ipfail

[root@dm1 ha.d]# vi haresources

#dm1IPaddr::192.168.0.180/32/eth0 drbddisk::mysql_dataFilesystem::/dev/drbd1::/data::ext4 mysqld

dm1 IPaddr::192.168.0.180/32/eth0drbd_primary

說明:

drbddisk::data   <==啓動drbd data資源,至關於執行/etc/ha.d/resource.d/drbddiskdata stop/start操做

Filesystem::/dev/drbd1::/data::ext3  <==drbd分區掛載到/data目錄,至關於執行/etc/ha.d/resource.d/Filesystem/dev/drbd1 /data ext3 stop/start <==至關於系統中執行mount  /dev/drbd1  /data

mysql  <==啓動mysql服務腳本,至關於/etc/init.d/mysql stop/start

資源切換腳本:

drbd_primary  resource-group用來指定須要Heartbeat託管的服務,也就是這些 服務能夠由Heartbeat來啓動和關閉。若是要託管這些服務,就必須將服務寫成能夠經過start/stop來啓動和關閉的腳步,而後放到/etc /init.d/或者/etc/ha.d/resource.d/目錄下,Heartbeat會根據腳本的名稱自動去/etc/init.d或者/etc /ha.d/resource.d/目錄下找到相應腳步進行啓動或關閉操做。

本腳本複製drbd的切換,已經mysql服務的啓動和關閉:

[root@dm1 ~]# cat drbd_primary 
#!/bin/sh
case "$1" in
start)
    drbdadm primary mysql_data
    mount /dev/drbd1 /data
   /etc/init.d/mysqld start
;;
stop)
   /etc/init.d/mysqld stop
   umount /dev/drbd1
   drbdadm secondary mysql_data
;;
esac
exit 0

啓動heartbeat:

# /etc/init.d/heartbeatstart

# chkconfig heartbeat off

說明:關閉開機自啓動,當服務器重啓時,須要人工去啓動

heartbeat的管理:

    配置好heartbeat以後,須要將mysql從自啓動服務器中去掉,由於主heartbeat啓動的時候會掛載drdb文件系統以及啓動 mysql,切換的時候會將主上的mysql中止並卸載文件系統,從上會掛載文件系統,並啓動mysql。所以須要作以下操做(兩臺服務器):

# chkconfig mysqld off

# chkconfig heartbeat off

# chkconfig drbd off     

#!/bin/sh

#

# This script will be executed *after* all the other  init scripts.

# You can put your own initialization stuff in here if  you don't

# want to do the full Sys V style init stuff.

touch /var/lock/subsys/local

modprobe drbd  #必須先加載模塊,這也是由於將啓動命令放在這裏的緣由

/etc/init.d/drbd start 

/etc/init.d/heartbeat start


3、 MySQL安裝部署

注意:兩臺數據庫都安裝mysql服務,dm2只安裝到make install便可,mysqld服務不要設置爲開機自啓動

二進制安裝:

[root@dm1 ~]# tar xfmysql-5.5.49-linux2.6-x86_64.tar.gz

[root@dm1 ~]# groupadd mysql

[root@dm1 ~]# useradd -g mysql -M -s/sbin/nologin mysql

[root@dm1 ~]# mv mysql-5.5.49-linux2.6-x86_64/usr/local/mysql-5.5.49

[root@dm1 ~]# echo'PATH=/usr/local/mysql/bin:$PATH' >>/etc/profile     

[root@dm1 ~]# source /etc/profile

[root@dm1 ~]# drbdadm up all

[root@dm1 ~]# drbdadm primary all

[root@dm1 ~]# mount /dev/drbd1 /data

說明:數據庫存放數據的目錄是drbd分區

[root@dm1~]# df -h

Filesystem      Size Used Avail Use% Mounted on

/dev/sda3        14G 2.5G   11G  19% /

tmpfs           238M     0 238M   0% /dev/shm

/dev/sda1       190M  52M  129M  29% /boot

/dev/drbd1      4.8G  10M  4.6G   1% /data

[root@dm1~]# chown -R mysql:mysql /data

[root@dm1~]# chown -R mysql.mysql /usr/local/mysql-5.5.49

[root@dm1~]# ln -s /usr/local/mysql-5.5.49/ /usr/local/mysql

[root@dm1~]#  cd /usr/local/mysql

[root@dm1mysql]# cp support-files/mysql.server /etc/init.d/mysqld

[root@dm1mysql]# sed –i 's#datadir=#datadir=/data#g' /etc/init.d/mysqld

說明:修改mysql啓動腳本,指定數據庫的目錄爲/data

[root@dm1mysql]# sed -i 's#basedir=#basedir=/usr/local/mysql#g' /etc/init.d/mysqld

[root@dm1mysql]# ./scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data --user=mysql

[root@dm1mysql]# cp support-files/my-huge.cnf /etc/my.cnf

[root@dm1mysql]# /etc/init.d/mysqld start

StartingMySQL.. SUCCESS!

[root@dm1mysql]# netstat -tunlp|grep 3306

tcp        0     0 0.0.0.0:3306               0.0.0.0:*                   LISTEN      14838/mysqld       

[root@dm1mysql]# chkconfig mysqld off

[root@dm1~]# mysql -uroot -e "show databases;"

mysql:Unknown OS character set 'GB18030'. #服務端的字符集得設置下

mysql:Switching to the default character set 'latin1'.

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

|Database           |

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

|information_schema |

|mysql              |

|performance_schema |

|test               |

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

經過my.cnf文件增長
兩個參數:
1.在[mysqld]下添加
default-character-set=utf8(mysql 5.5 版本添加character-set-server=utf8)
2.在[client]下添加
default-character-set=utf8
   這樣咱們建數據庫建表的時候就不用特別指定utf8的字符集了。配置文件裏的這種寫法解決了數據存儲和比較的問題,可是對客戶端的鏈接是沒有做用的,客戶端這時候通常須要指定utf8方式鏈接才能避免亂碼。也就是傳說總的set names命令。事實上,set names utf8命令對應的是服務器端如下幾個命令:
SET character_set_client = utf8;
SET character_set_results = utf8;
SET character_set_connection = utf8;
  但這三個參數是不能寫在配置文件my.cnf裏的。只能經過set命令來動態修改。咱們須要的是在配置文件裏寫好一勞永逸的辦法。那麼這時候,是否有在服務端解決問題的辦法呢,可行的思路是在init_connect裏設置。這個命令在每一個普通用戶鏈接上來的時候都會觸發執行,能夠在[mysqld]部分增長如下一行設置鏈接字符集:
在[mysqld]下添加:
init_connect = 'SET NAMES utf8'
總結:
一、首選在編譯安裝MySQL的時候指定兩個參數使用utf8編碼。
二、次選在配置文件my.cnf或my.ini設定兩個參數,同時設置init_connect參數。
三、第三在配置文件my.cnf或my.ini設定兩個參數,同時客戶端的鏈接指定set names命令。
四、在配置文件my.cnf裏的client和server處加入default-character-set參數方便管理。

[root@dm1~]# mysql -uroot -e "show databases;"

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

|Database           |

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

|information_schema |

|mysql              |

|performance_schema |

|test               |

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

[root@dm1~]# mysql -uroot -e "show variables like '%char%';"

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

|Variable_name            | Value                                   |

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

|character_set_client     | utf8                                    |

|character_set_connection| utf8                                   |

|character_set_database   | utf8                                    |

|character_set_filesystem| binary                                 |

|character_set_results    | utf8                                    |

|character_set_server     | utf8                                    |

|character_set_system     | utf8                                    |

|character_sets_dir      | /usr/local/mysql-5.5.49/share/charsets/|

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

 

[root@dm1ha.d]# /etc/init.d/heartbeat start

[root@dm1~]# ip a|grep eth0

eth0:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000

    link/ether 00:0c:29:92:b5:37 brdff:ff:ff:ff:ff:ff

    inet 10.0.0.61/24 brd 10.0.0.255 scopeglobal eth0

    inet 192.168.0.180/32 scope global eth0

    inet6 fe80::20c:29ff:fe92:b537/64 scope link

       valid_lft forever preferred_lft forever

[root@dm1~]# netstat -tunlp

Active Internet connections(only servers)

Proto Recv-Q Send-Q LocalAddress               ForeignAddress             State       PID/Program name  

tcp        0     0 0.0.0.0:3306               0.0.0.0:*                   LISTEN      29981/mysqld       

tcp        0     0 10.0.0.61:7788              0.0.0.0:*                   LISTEN      -                  

tcp        0     0 0.0.0.0:52668              0.0.0.0:*                   LISTEN      1048/sshd          

tcp        0     0 :::52668                   :::*                        LISTEN      1048/sshd          

udp        0     0 0.0.0.0:694                0.0.0.0:*                              29218/heartbeat: wr

udp        0     0 0.0.0.0:55111              0.0.0.0:*                              29218/heartbeat: wr

[root@dm1~]# df -h        

Filesystem      Size Used Avail Use% Mounted on

/dev/sda3        14G 2.5G   11G  20% /

tmpfs           238M     0 238M   0% /dev/shm

/dev/sda1       190M  52M  129M  29% /boot

/dev/drbd1      4.8G  40M  4.5G   1% /data

 

[root@dm2 ha.d]# ln -s /usr/local/mysql-5.5.49/ /usr/local/mysql

[root@dm2 ha.d]# chown -R mysql.mysql /usr/local/mysql-5.5.49

[root@dm2 ha.d]# chown -R mysql:mysql /data

[root@dm2 ha.d]# cd /usr/local/mysql

[root@dm2 mysql]# cp support-files/mysql.server /etc/init.d/mysqld

[root@dm2 mysql]# sed –i 's#datadir=#datadir=/data#g' /etc/init.d/mysqld

說明:修改mysql啓動腳本,指定數據庫的目錄爲/data

[root@dm2 mysql]# sed -i 's#basedir=#basedir=/usr/local/mysql#g' /etc/init.d/mysqld

[root@dm2 mysql]# ./scripts/mysql_install_db --basedir=/usr/local/mysql --datadir=/data --user=mysql

[root@dm2 mysql]# cp support-files/my-huge.cnf /etc/my.cnf

注意:同上dm1,#dm2服務端的字符集得設置下,dm2的mysql服務不用啓動,由heartbeat接管時來啓動!

[root@dm2~]# modprobe drbd

[root@dm2~]# lsmod | grepdrbd

[root@dm2~]# drbdadm create-md mysql_data

[root@dm2~]# /etc/init.d/drbd start

[root@dm2~]# /etc/init.d/heartbeat start

[root@dm2~]# netstat -tunlp

Active Internet connections(only servers)

Proto Recv-Q Send-Q LocalAddress               ForeignAddress             State       PID/Program name  

tcp        0     0 0.0.0.0:52668              0.0.0.0:*                   LISTEN      1126/sshd          

tcp        0     0 :::52668                    :::*                        LISTEN      1126/sshd          

udp        0     0 0.0.0.0:694                0.0.0.0:*                              3344/heartbeat: wri

udp  0  00.0.0.0:22105   0.0.0.0:*                               3344/heartbeat:wri

 

先看看兩臺服務器的狀態:

[root@dm1~]# df -hT

Filesystem     Type  Size  Used Avail Use% Mounted on

/dev/sda3      ext4   14G  2.5G   11G 20% /

tmpfs          tmpfs 238M     0  238M  0% /dev/shm

/dev/sda1      ext4  190M   52M  129M 29% /boot

/dev/drbd1     ext4  4.8G   40M  4.5G  1% /data

[root@dm2~]# df -hT

Filesystem     Type  Size  Used Avail Use% Mounted on

/dev/sda3      ext4   14G  2.5G   11G 20% /

tmpfs          tmpfs 238M     0  238M  0% /dev/shm

/dev/sda1      ext4  190M   52M  129M 29% /boot

#能夠看見掛載在第一臺服務器。

 

4、故障切換測試

測試方法:

1.停掉dm1上的mysqld,看看是否切換(由於heartheat不檢查服務的可用性,所以須要經過額外的腳原本實現)。
2.停掉dm1的heartheat看看是否能正常切換。
3.停掉dm1的網絡或者直接將dm1系統shutdown,看看可否正常切換。
4.啓動dm1的heartbeat看看是否能正常切換回來。
5.從新啓動dm1看看可否切換,過程是否OK。
注意:這裏說的切換是指是否是已經將mysql停掉、是否卸載了文件系統等等。

我就中止dm1(10.0.0.61)上的heartbeat來測試是否會自動切換,這裏除了第一條沒法實現,其餘的均可以切換:

對主Primary/Secondary模型的drbd服務來說,在某個時刻[只能有一個節點爲Primary],所以,要切換兩個節點的角色,只能在先將原有的Primary節點設置爲Secondary後,才能將原來的Secondary節點設置爲Primary。

dm1:

[root@dm1~]# /etc/init.d/heartbeat stop

Stopping High-Availabilityservices: Done.

[root@dm1~]# ip a|grep eth0

eth0:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000

    link/ether 00:0c:29:92:b5:37 brdff:ff:ff:ff:ff:ff

    inet 10.0.0.61/24 brd 10.0.0.255 scopeglobal eth0

    inet6 fe80::20c:29ff:fe92:b537/64 scopelink

       valid_lft forever preferred_lft forever

 [root@dm1 ~]# df -hT

Filesystem     Type  Size  Used Avail Use% Mounted on

/dev/sda3      ext4   14G  2.5G   11G 20% /

tmpfs          tmpfs 238M     0  238M  0% /dev/shm

/dev/sda1      ext4  190M   52M  129M 29% /boot

 [root@dm1 ~]# netstat -tunlp

Active Internet connections(only servers)

Proto Recv-Q Send-Q LocalAddress               ForeignAddress             State       PID/Program name  

tcp        0     0 0.0.0.0:52668               0.0.0.0:*                   LISTEN      1126/sshd          

tcp        0     0 :::52668                   :::*                        LISTEN      1126/sshd    

[root@dm1 ~]# cat /proc/drbd

version: 8.4.7-1(api:1/proto:86-101)

GIT-hash: 3a6a769340ef93b1ba2792c6461250790795db49build by mockbuild@Build64R6, 2016-01-12 13:27:11

 

 1: cs:Connected ro:Secondary/Primaryds:UpToDate/UpToDate C r-----

ns:5221557 nr:316 dw:780 dr:5227792 al:16 bm:0 lo:0 pe:0 ua:0ap:0 ep:1 wo:f oos:0

dm2:

[root@dm2~]# df -hT

Filesystem     Type  Size  Used Avail Use% Mounted on

/dev/sda3      ext4   14G  2.5G   11G 20% /

tmpfs          tmpfs 238M     0  238M  0% /dev/shm

/dev/sda1      ext4  190M   52M  129M 29% /boot

/dev/drbd1     ext4  4.8G   40M  4.5G  1% /data

[root@dm2~]# netstat -tunlp

Active Internet connections(only servers)

Proto Recv-Q Send-Q LocalAddress               ForeignAddress             State       PID/Program name  

tcp        0     0 0.0.0.0:3306               0.0.0.0:*                   LISTEN      4113/mysqld        

tcp        0     0 0.0.0.0:52668              0.0.0.0:*                   LISTEN      1126/sshd          

tcp        0     0 :::52668                   :::*                        LISTEN      1126/sshd          

udp        0     0 0.0.0.0:694                0.0.0.0:*                              3344/heartbeat: wri

udp        0     0 0.0.0.0:22105              0.0.0.0:*                              3344/heartbeat: wri

[root@dm2~]# ip a|grep eth0

eth0:<BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen1000

    link/ether 00:0c:29:5b:bc:19 brdff:ff:ff:ff:ff:ff

    inet 10.0.0.62/24 brd 10.0.0.255 scopeglobal eth0

    inet 192.168.0.180/32 scope global eth0

    inet6 fe80::20c:29ff:fe5b:bc19/64 scopelink

       valid_lft forever preferred_lft forever

[root@dm2~]# 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

 

 1: cs:Connected ro:Primary/Secondaryds:UpToDate/UpToDate C r-----

ns:316 nr:5221557 dw:5221873 dr:6036 al:14 bm:0 lo:0 pe:0 ua:0ap:0 ep:1 wo:f oos:0

對於mysqld服務掛掉的狀況沒法實現自動切換,須要一個腳原本幫助咱們完成。

 

5、可能存在的問題

報錯1:
問題描述:設備被其餘人佔用,沒法中止或者下線資源
0: State change failed: (-12) Device is held open by someone
解決辦法:查看是否有設備掛載,umount便可
報錯2:
問題描述:0:mydrbd WFConnection Primary/UnknownUpToDate/DUnknown C r—–,即總有一個節點是未知狀態
解決辦法:
主節點上執行:
drbdadm connect all(all能夠換成本身定義的DRBD資源名稱)
從節點上執行:
drbdadm -- --discard-my-data connect all

報錯3:
configure: error: Cannot build utils without flex, either install flex or passthe –without-utils option.
解決辦法:
yum -y intalls flex
報錯4:
make: [check-kdir] error 1
解決辦法:yum install -y kernel-devel
報錯5:
SORRY, kernel makefile not found.
You need to tell me a correct KDIR,
Or install the neccessary kernel source packages.
報錯6:
‘drbd’ not defined in your config (for this host).
這個由於沒有加載到drbd模塊
報錯7:
啓動報錯:
Command ‘drbdmeta 0 v08 /dev/sdb1 internal create-md’ terminated with exit code40
這是由於sdb1已經有文件系統了,已經有數據存在了
解決方法:
[root@node1 ~]# dd  if=/dev/zero bs=1M count=1 of=/dev/sdb1


總結

   搭建還不算複雜,可是也踩了很多坑,好比yum安裝的heartbeat沒有drbddisk腳本。該方案的優勢是安全性高、穩定性高、可用性高,出現故障自動切換,可是缺點也很明顯,只有一臺服務器提供服務,成本相對較高。不方便擴展。可能會發生腦裂。當mysql服務掛掉或者不可用的狀況下不能進行自動切換,須要經過crm模式實現或者額外的腳本實現(好比shell腳本監測到master的mysql不可用就將主上的heartbeat停掉, 這樣就會切換到backup中去)。監控也特別重要,可使用nagios或者zabbix監控。


高可用腦裂問題及解決方案

(1)、致使裂腦發生的緣由

一、高可用服務器之間心跳鏈路故障,致使沒法相互檢查心跳

二、高可用服務器上開啓了防火牆,阻擋了心跳檢測

三、高可用服務器上網卡地址等信息配置不正常,致使發送心跳失敗

四、其餘服務配置不當等緣由,如心跳方式不一樣,心跳廣播衝突,軟件BUG等

(2)、防止裂腦一些方案

一、加冗餘線路

二、檢測到裂腦時,強行關閉心跳檢測(遠程關閉主節點,控制電源的電路fence)

三、作好腦裂的監控報警

四、報警後,備節點在接管時設置比較長的時間去接管,給運維人員足夠的時間去處理(人爲處理)

五、啓動磁盤鎖,正在服務的一方鎖住磁盤,裂腦發生時,讓對方徹底搶不走"共享磁盤資源"

磁盤鎖存在的問題:

使用鎖磁盤會有死鎖的問題,若是佔用共享磁盤的一方不主動"解鎖"另外一方就永遠得不到共享磁盤,假如服務器節點忽然死機或崩潰,就不可能執行解鎖命令,備節點也就沒法接管資源和服務了,有人在HA中設計了智能鎖,正在提供服務的一方只在發現心跳所有斷開時纔會啓用磁盤鎖,平時就不上鎖

DRDB各類狀態查看:

查看資源的鏈接狀態

# drbdadm cstate mysql_data
Connected
資源的鏈接狀態;一個資源可能有如下鏈接狀態中的一種
StandAlone  獨立的:網絡配置不可用;資源尚未被鏈接或是被管理斷開(使用 drbdadm disconnect 命令),或是因爲出現認證失敗或是腦裂的狀況
Disconnecting  斷開:斷開只是臨時狀態,下一個狀態是StandAlone獨立的
Unconnected  懸空:是嘗試鏈接前的臨時狀態,可能下一個狀態爲WFconnection和WFReportParams
Timeout  超時:與對等節點鏈接超時,也是臨時狀態,下一個狀態爲Unconected  懸空
BrokerPipe:與對等節點鏈接丟失,也是臨時狀態,下一個狀態爲Unconected懸空
NetworkFailure:與對等節點推進鏈接後的臨時狀態,下一個狀態爲Unconected 懸空
ProtocolError:與對等節點推進鏈接後的臨時狀態,下一個狀態爲Unconected 懸空
TearDown 拆解:臨時狀態,對等節點關閉,下一個狀態爲Unconected懸空
WFConnection:等待和對等節點創建網絡鏈接
WFReportParams:已經創建TCP鏈接,本節點等待從對等節點傳來的第一個網絡包
Connected 鏈接:DRBD已經創建鏈接,數據鏡像如今可用,節點處於正常狀態
StartingSyncS:徹底同步,有管理員發起的剛剛開始同步,將來可能的狀態爲SyncSource或PausedSyncS
StartingSyncT:徹底同步,有管理員發起的剛剛開始同步,下一狀態爲WFSyncUUID
WFBitMapS:部分同步剛剛開始,下一步可能的狀態爲SyncSource或PausedSyncS
WFBitMapT:部分同步剛剛開始,下一步可能的狀態爲WFSyncUUID
WFSyncUUID:同步即將開始,下一步可能的狀態爲SyncTarget或PausedSyncT
SyncSource:以本節點爲同步源的同步正在進行
SyncTarget:以本節點爲同步目標的同步正在進行
PausedSyncS:以本地節點是一個持續同步的源,可是目前同步已經暫停,多是由於另一個同步正在進行或是使用命令(drbdadm pause-sync)暫停了同步
PausedSyncT:以本地節點爲持續同步的目標,可是目前同步已經暫停,這能夠是由於另一個同步正在進行或是使用命令(drbdadm pause-sync)暫停了同步
VerifyS:以本地節點爲驗證源的線上設備驗證正在執行
VerifyT:以本地節點爲驗證目標的線上設備驗證正在執行

查看資源角色的命令

# drbdadm role mysql_data
Primary/Secondary (在前面爲當前節點)
Parimary 主:資源目前爲主,而且可能正在被讀取或寫入,若是不是雙主只會出如今兩個節點中的其中一個節點上
Secondary 次:資源目前爲次,正常接收對等節點的更新
Unknown 未知:資源角色目前未知,本地的資源不會出現這種狀態

查看硬盤狀態

# drbdadm dstate mysql_data
UpToDate/UpToDate
本地和對等節點的硬盤有可能爲下列狀態之一:
Diskless  無盤:本地沒有塊設備分配給DRBD使用,這表示沒有可用的設備,或者使用drbdadm命令手工分離或是底層的I/O錯誤致使自動分離
Attaching:讀取無數據時候的瞬間狀態
Failed  失敗:本地塊設備報告I/O錯誤的下一個狀態,其下一個狀態爲Diskless 無盤
Negotiating:在已經鏈接的DRBD設置進行Attach讀取無數據前的瞬間狀態
Inconsistent:數據是不一致的,在兩個節點上(初始的徹底同步前)這種狀態出現後當即建立一個新的資源。此外,在同步期間(同步目標)在一個節點上出現這種狀態
Outdated:數據資源是一致的,可是已通過時
DUnknown:當對等節點網絡鏈接不可用時出現這種狀態
Consistent:一個沒有鏈接的節點數據一致,當創建鏈接時,它決定數據是UpToDate或是Outdated
UpToDate:一致的最新的數據狀態,這個狀態爲正常狀態


查看同步進度

# cat /proc/drbd 或者 執行/usr/local/drbd/sbin/drbd-overview或者 service drbd status
version: 8.4.3 (api:1/proto:86-101)
GIT-hash: 89a294209144b68adb3ee85a73221f964d3ee515 build byroot@localhost.localdomain, 2016-04-24 20:16:24
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r—–
ns:2767088 nr:0 dw:0 dr:2774680 al:0 bm:168 lo:0 pe:1 ua:7 ap:0 ep:1 wo:foos:18202972
[=>………………] sync’ed: 13.3% (17776/20476)M
finish: 0:12:59 speed: 23,344 (22,492) K/sec
因而可知:進度已經完成了13.3%,傳輸速度大概22M/S
注:
ds  是磁盤狀態信息
dw 是磁盤寫信息
dr  是磁盤讀信息

cat /proc/drbd 、/usr/local/drbd/sbin/drbd-overview或者 service drbd status執行後顯示的信息格式會有所不一樣

注意點:

1)mount drbd設備之前必須把設備切換到primary狀態。
2)兩個節點中,同一時刻只能有一臺處於primary狀態,另外一臺處於secondary狀態。
3)處於secondary狀態的服務器上不能加載drbd設備。
4)主備服務器同步的兩個分區大小最好相同,這樣不至於浪費磁盤空間,由於drbd磁盤鏡像至關於網絡raid1。


參考資料:

三木的人生——3mu.me

http://shineforever.blog.51cto.com/1429204/1633519

http://oldboy.blog.51cto.com/2561410/1240412

http://oldboy.blog.51cto.com/2561410/515345

相關文章
相關標籤/搜索