MySQL高可用方案之DRBD+MySQL+RHCS(上)

powdba發表於2018-12-12

MySQL作為最流行的資料庫,它的高可用方案也是多種多樣,其中用的比較多的是MHA+增強版半同步。但是客戶使用的是DRBD+RHCS的方案,通過各方尋找安裝資料,最終形成一個完整的安裝文件,供參考

一、DRBD介紹

1.1 DRBD基本功能

Distributed Replicated Block Device(DRBD)是一種基於軟體的,無共享,複製的儲存解決方案,在伺服器之間的對塊裝置(硬碟,分割槽,邏輯卷等)進行映象。
DRBD是將不同機器上的兩塊大小相同的硬碟或是兩個分割槽讓它們的每一位都對齊,從而當使用者空間有資料要儲存到主節點磁碟時,工作在核心空間的DRBD會監控資料,一旦發現資料是要儲存到定義了DRBD的分割槽上後,就會把資料複製一份通過網路傳送到備用節點上來。備用節點上執行一個服務時刻可以接收對方發來的資料,然後接到核心中,核心中的DRBD接收到資料後通過核心儲存到磁碟上。雙方式通過DRBD協議按位儲存資料。
在高可用(HA)中使用DRBD功能,可以代替使用一個共享盤陣。本地(主節點)與遠端主機(備節點)的資料可以保證實時同步。當本地系統出現故障時,遠端主機上還會保留有一份相同的資料,可以繼續使用。需要說明一點的是DRBD只支援兩個節點不支援多節點。
DRBD映象資料
實時性:當應用程式修改磁碟上的資料時,複製立即發生。
透明性:應用程式不需要意識到資料儲存在多個主機上。
同步或非同步:通過同步映象,在所有主機上執行寫操作後,才會通知應用程式寫入完成。使用非同步映象時,應用程式在本地完成寫入操作時會收到寫入完成的通知,這通常是在它們傳播到其他主機之前。

1.2 核心模組

DRBD的核心功能是通過Linux核心模組實現的。具體而言,DRBD包含一個虛擬的塊裝置,因此DRBD位於系統的I/O堆疊底部附近。因此,DRBD非常靈活和多功能,這使得它成為適用於為任何應用程式增加高可用性的複製解決方案。
DRBD在Linux I/O堆疊的位置:

File system:通過API向外輸出介面。
Buffer cache:是用來快取資料和後設資料的。
Disk scheduler:是用來排序記憶體中即將要寫入磁碟的資料合併讀請求,合併寫請求一同寫入磁碟提高速度(對於機械硬碟如果排程器能把隨機讀寫操作轉換為順序讀寫操作將提升很高的磁碟效能;而固態硬碟沒有機械臂就沒有順序讀寫的概念)。
Disk driver:當排程器合併完成之後將多個I/O轉為一個I/O最終還是要轉為磁碟的機械臂移動扇區的讀寫;這些都是由磁碟驅動來完成,驅動知道怎麼找扇區怎麼控制機械臂運算元據;一般驅動都是在核心中執行的。
DRBD工作的位置在File system的buffer cache和Disk scheduler之間,通過tcp/ip發給另外一臺主機到對方的tcp/ip最終傳送給對方的DRBD,再由對方的DRBD儲存在本地對應磁碟上,類似於一個網路RAID-1功能。我們知道RAID1是在同一臺機器上使用兩塊大小相同的硬碟讓它們的每一位都對齊,從而RAID晶片實現將資料分兩份按位對應儲存到不同的磁碟上實現資料塊的同步。

1.3 底層裝置支援

DRBD需要構建在底層裝置之上,然後構建出一個塊裝置出來。對於使用者來說,一個DRBD裝置,就像是一塊物理的磁碟,可以在上面內建立檔案系統。DRBD所支援的底層裝置有以下這些類:
1)一個磁碟,或者是磁碟的某一個分割槽;
2)一個soft raid裝置;
3)一個LVM的邏輯卷;
4)一個EVMS(Enterprise Volume Management System,企業卷管理系統)的卷;
5)其他任何的塊裝置。

1.4 使用者空間管理工具

DRBD附帶一組管理工具,與核心模組進行通訊以配置和管理DRBD資源。
drbdadm
高層的DRBD程式管理套件工具,它從配置檔案/etc/drdb.conf中獲取所有配置引數。drbdadm為drbdsetup何drbdmeta兩個命令充當程式的前端應用,執行drbdadm實際是執行drbdsetup和drbdmeta兩個命令。
drbdsetup
可以讓使用者配置已經載入在核心中執行的DRBD模組,它是底層的DRBD程式管理套件工具。使用該命令時,所有的配置引數都需要直接在命令列中定義,雖然命令靈活,但是大大的降低了命令的簡單易用性,因此很多的使用者很少使用drbdsetup。
drbdmeta
允許建立,轉儲,恢復和修改DRBD後設資料結構。這個命令也是使用者極少用到的。

1.5 DRBD Resource(資源)

在DRBD中,資源是指可複製資料裝置的總稱。這些包括:
資源名稱:只能為ASCII碼,但空白字元除外。
DRBD裝置:在雙方節點上,此DRBD裝置的裝置檔案一般為/dev/drbd0,其主裝置號由IANA規定好的147。
磁碟:在雙方節點上各自提供的儲存裝置。
網路配置:雙方資料同時所使用的網路屬性如網路頻寬、資料加密等。

二、DRBD特點

2.1 DRBD模型

DRBD主從模型:DRBD主從架構中,主節點可以讀寫資料而從節點不能讀寫,連掛載都不允許,否則會造成檔案系統崩潰,但是主從的節點可以相互切換,如可以把主節點分割槽解除安裝後把主節點轉為從,然後把分割槽掛在到從節點上,再把從轉為主。
DRBD雙主模型:由於DRBD是在兩臺獨立的機器上實現資料塊同步,所以單憑在一個節點上寫資料時施加鎖機制而另外一個節點要寫資料時看不到對方施加的鎖,因此會照成資料損壞。但是如果把DRBD用在高可用叢集中就可以實現雙主模型,在高可用中把DRBD定義成主從資源基於分散式檔案鎖DLM加叢集檔案系統gfs或ocfs,這樣一來當一端在寫入資料時因為是DLM+GFS,所以就會通知給另外一端的DRBD從而避免資料損壞(雙主模型並不是並行讀寫)。

2.2 DRBD資料同步協議

由於DRBD將資料傳送給對端伺服器之後還要確定對方的回應以確定資料是否安全儲存,然後DRBD程式才退出,最終應用程式完成資料儲存。這樣一來DRBD傳送資料並接收到回應的時間就是應用程式執行的過程時間。所以又涉及到了資料安全跟效能之間平衡了,DRBD提供了非同步、半同步、同步等工作方式,自行考量選擇。
非同步複製:非同步複製協議。一旦本地磁碟寫入已經完成,資料包已在傳送佇列中,則寫被認為是完成的。在一個節點發生故障時,可能發生資料丟失,因為被寫入到遠端節點上的資料可能仍在傳送佇列。儘管,在故障轉移節點上的資料是一致的,但沒有及時更新。這通常是用於地理上分開的節點。
半同步複製:記憶體同步(半同步)複製協議。一旦本地磁碟寫入已完成且複製資料包達到了對等節點則認為寫在主節點上被認為是完成的。資料丟失可能發生在參加的兩個節點同時故障的情況下,因為在傳輸中的資料可能不會被提交到磁碟。
同步複製:同步複製協議。只有在本地和遠端節點的磁碟已經確認了寫操作完成,寫才被認為完成。沒有任何資料丟失,所以這是一個群集節點的流行模式,但I / O吞吐量依賴於網路頻寬。一般使用協議C,但選擇C協議將影響流量,從而影響網路時延。為了資料可靠性,我們在生產環境使用時須慎重選項使用哪一種協議。

三、安裝DRBD步驟

CentOS 6 YUM安裝DRBD

這裡使用yum安裝,首先安裝yum源,然後再安裝BRBD。

# rpm -Uvh https://www.elrepo.org/elrepo-release-6-8.el6.elrepo.noarch.rpm
# rpm --import /etc/pki/rpm-gpg/RPM-GPG-KEY-elrepo.org

先升級核心,不然安裝不上DRBD,我的核心舊的是3.10.0-327,升級後的是3.10.0-693。

# yum -y install kernel-devel kernel-headers flex kernel
# rpm -qa | grep kernel
kernel-3.10.0-327.el7.x86_64
kernel-3.10.0-693.5.2.el7.x86_64

安裝drbd核心模組和管理工具。

# yum -y install drbd84-utils kmod-drbd84

然後要重啟作業系統,使用新核心。啟動時確認grub.conf裡面預設啟動的是新核心。

# reboot

載入drbd核心模組,insmod與modprobe都能載入kernel module,不過一般差別於modprobe能夠處理module載入的依賴問題。

# modprobe drbd
# lsmod | grep drbd
drbd 397041 3
libcrc32c 12644 2 xfs,drbd

載入核心如果出現“FATAL: Module drbd not found.”錯誤。這是因為系統預設的核心並不支援此模組,所以需要更新核心。
配置開機自動載入模組,開機會載入此目錄/etc/sysconfig/modules/;

# cat /etc/sysconfig/modules/drbd.modules
#!/bin/sh
/sbin/modinfo -F filename drbd > /dev/null 2>&1
if [ $? -eq 0 ]; then
    /sbin/modprobe drbd
fi

賦予執行許可權:

# chmod 755 /etc/sysconfig/modules/drbd.modules

安裝指南:http://docs.linbit.com/doc/users-guide-84/s-distro-packages

四、DRBD單主模型配置

1)配置前準備

DRBD1主機IP:10.10.110.231
DRDB2主機IP:10.10.110.230

1.1 關閉防火牆和SELINUX
# service iptables stop
# setenforce 0
1.2 兩臺主機分別新增hosts
# cat /etc/hosts
10.10.110.231 DRBD1
10.10.110.230 DRBD2
1.3 兩臺主機基於SSH通訊

node1主機配置ssh基於祕鑰通訊

# ssh-keygen -t rsa -P ``
# ssh-copy-id -i /root/.ssh/id_rsa.pub root@DRBD2

node2主機配置ssh基於祕鑰通訊

# ssh-keygen -t rsa -P ``
# ssh-copy-id -i /root/.ssh/id_rsa.pub root@DRBD1
1.4 兩臺主機需要提供一個磁碟分割槽或單獨一個磁碟,兩節點磁碟大小需要一致,磁碟不需要格式化
# fdisk -l
Disk /dev/sdb: 34.4 GB, 34359738368 bytes, 67108864 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
1.5 兩臺主機需要時間同步(如果時間不同步)

修正時區,直接寫入到/etc/profile即可。

# TZ=`Asia/Shanghai`; export TZ

2)配置DRBD

drbd的主配置檔案為/etc/drbd.conf,為了管理的便捷性,目前通常會將些配置檔案分成多個部分,且都儲存至/etc/drbd.d目錄中,主配置檔案中僅使用”include”指令將這些配置檔案片斷整合起來。通常,/etc/drbd.d目錄中的配置檔案為global_common.conf和所有以.res結尾的檔案。其中global_common.conf中主要定義global段和common段,而每一個.res的檔案用於定義一個資源。
在配置檔案中,global段僅能出現一次,且如果所有的配置資訊都儲存至同一個配置檔案中而不分開為多個檔案的話,global段必須位於配置檔案的最開始處。目前global段中可以定義的引數僅有minor-count, dialog-refresh, disable-ip-verification和usage-count。
common段則用於定義被每一個資源預設繼承的引數,可以在資源定義中使用的引數都可以在common段中定義。實際應用中,common段並非必須,但建議將多個資源共享的引數定義為common段中的引數以降低配置檔案的複雜度。
resource段則用於定義drbd資源,每個資源通常定義在一個單獨的位於/etc/drbd.d目錄中的以.res結尾的檔案中。資源在定義時必須為其命名,名字可以由非空白的ASCII字元組成。每一個資源段的定義中至少要包含兩個host子段,以定義此資源關聯至的節點,其它引數均可以從common段或drbd的預設中進行繼承而無須定義。
下面的操作在node1上完成。主配置檔案:

[root@DRBD1~]# cat /etc/drbd.conf
# You can find an example in  /usr/share/doc/drbd.../drbd.conf.example
include "drbd.d/global_common.conf";
include "drbd.d/*.res";

配置/etc/drbd.d/global-common.conf

[root@DRBD1~]# vim /etc/drbd.d/global_common.conf
global {
        usage-count no;  //在網際網路上有人使用DRBD就會通知作者;
        # minor-count dialog-refresh disable-ip-verification
}
common {                 //定義如果DRBD沒有額外定義屬性那麼就繼承common屬性;
        protocol C;      //預設使用C同步協議;
        handlers {
            pri-on-incon-degr "/usr/lib/drbd/notify-pri-on-incon-degr.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
            pri-lost-after-sb "/usr/lib/drbd/notify-pri-lost-after-sb.sh; /usr/lib/drbd/notify-emergency-reboot.sh; echo b > /proc/sysrq-trigger ; reboot -f";
            local-io-error "/usr/lib/drbd/notify-io-error.sh; /usr/lib/drbd/notify-emergency-shutdown.sh; echo o > /proc/sysrq-trigger ; halt -f";
            //啟用上面三項即可
            # fence-peer "/usr/lib/drbd/crm-fence-peer.sh";
            # split-brain "/usr/lib/drbd/notify-split-brain.sh root";
            # out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";
            # before-resync-target "/usr/lib/drbd/snapshot-resync-target-lvm.sh -p 15 -- -c 16k";
            # after-resync-target /usr/lib/drbd/unsnapshot-resync-target-lvm.sh;
        }
        startup {   //定義第一次DRBD對接超時時間;
            # wfc-timeout 120;
            # degr-wfc-timeout 120;
        }
        disk {      //啟用如果磁碟有故障就將DRBD拆除不再同步;
            on-io-error detach;
            #fencing resource-only;
        }
        net {       //啟用資料傳輸加密
            cram-hmac-alg "sha1";
            shared-secret "mydrbdlab";
        }
        syncer {    //定義資料同步時的速率
            rate 1000M;
        }
}

net:網路配置相關的內容,可以設定是否允許雙主節點(allow-two-primaries)等。
startup:啟動時候的相關設定,比如設定啟動後誰作為primary(或者兩者都是primary:become-primary-on both)
syncer: 同步相關的設定。可以設定“重新”同步(re-synchronization)速度(rate)設定,也可以設定是否線上校驗節點之間的資料一致性 (verify-alg 檢測演算法有md5,sha1以及crc32等)。資料校驗可能是一個比較重要的事情,在開啟線上校驗功能後,我們可以通過相關命令(drbdadm verify resource_name)來啟動線上校驗。在校驗過程中,drbd會記錄下節點之間不一致的block,但是不會阻塞任何行為,即使是在該不一致的 block上面的io請求。當不一致的block發生後,drbd就需要有re-synchronization動作,而syncer裡面設定的rate 項,主要就是用於re-synchronization的時候,因為如果有大量不一致的資料的時候,我們不可能將所有頻寬都分配給drbd做re- synchronization,這樣會影響對外提提供服務。rate的設定和還需要考慮IO能力的影響。如果我們會有一個千兆網路出口,但是我們的磁碟 IO能力每秒只有50M,那麼實際的處理能力就只有50M,一般來說,設定網路IO能力和磁碟IO能力中最小者的30%的頻寬給re- synchronization是比較合適的(官方說明)。另外,drbd還提供了一個臨時的rate更改命令,可以臨時性的更改syncer的rate值: drbdsetup /dev/drbd0 syncer -r 100M。這樣就臨時的設定了re-synchronization的速度為100M。不過在re-synchronization結束之後,你需要通過 drbdadm adjust resource_name 來讓drbd按照配置中的rate來工作。
定義resource檔案/etc/drbd.d/r0.res,內容如下:

[root@DRBD1~]# vim /etc/drbd.d/r0.res
resource r0 {
  on DRBD1 {
    device /dev/drbd0;
    disk /dev/sdb;
    address 10.10.110.231:7789;
    meta-disk internal;
  }
  on DRBD2 {
    device /dev/drbd0;
    disk /dev/sdb;
    address 10.10.110.230:7789;
    meta-disk internal;
  }
}

以上檔案在兩個節點上必須相同,因此,可以基於ssh將剛才配置的檔案全部同步至另外一個節點。

[root@DRBD1~]# scp /etc/drbd.d/global_common.conf DRBD2:/etc/drbd.d/
[root@DRBD1~]# scp /etc/drbd.d/r0.res DRBD2:/etc/drbd.d/

3)在兩個節點上初始化已定義的資源並啟動服務

3.1 初始化資源,在Node1和Node2上分別執行drbdadm create-md resource_name,切記資源名稱只能是ASCII碼(輸入兩次yes)
# drbdadm create-md r0
You want me to create a v08 style flexible-size internal meta data block.
There appears to be a v08 flexible-size internal meta data block
already in place on /dev/sdb at byte offset 34359734272

Do you really want to overwrite the existing meta-data?
[need to type `yes` to confirm] yes

md_offset 34359734272
al_offset 34359701504
bm_offset 34358652928

Found ext3 filesystem
    33553372 kB data area apparently used
    33553372 kB left usable by current configuration

Even though it looks like this would place the new meta data into
unused space, you still need to confirm, as this is only a guess.

Do you want to proceed?
[need to type `yes` to confirm] yes

initializing activity log
initializing bitmap (1024 KB) to all zero
ioctl(/dev/sdb, BLKZEROOUT, [34358652928, 1048576]) failed: Inappropriate ioctl for device
Using slow(er) fallback.
100%
Writing meta data...
New drbd meta data block successfully created.
3.2 啟動服務,在Node1和Node2上分別執行
# service drbd start

啟動node1節點後,會一直去等待node2節點啟動drbd,一點兩個節點通訊成功後,node1節點就會馬上啟動完成。

3.3 檢視啟動狀態
# cat /proc/drbd
version: 8.4.10-1 (api:1/proto:86-101)
GIT-hash: a4d5de01fffd7e4cde48a080e2c686f9e8cebf4c build by mockbuild@, 2017-09-15 14:23:22
1: 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:52427164

也可以使用drbd-overview命令來檢視:

# drbd-overview
0:r0/0  Connected Secondary/Secondary Inconsistent/Inconsistent C r-----

從上面的資訊中可以看出此時兩個節點均處於Secondary狀態。於是,我們接下來需要將其中一個節點設定為Primary。
在要設定為Primary的節點上執行如下命令(我這裡在node1節點執行):

# drbdadm primary --force r0

注: 也可以在要設定為Primary的節點上使用如下命令來設定主節點。

# drbdadm -- --overwrite-data-of-peer primary r0

再次檢視狀態,可以發現資料同步過程已經開始(達到100%後再繼續操作):

# drbd-overview
1:r0/0  SyncSource Primary/Secondary UpToDate/Inconsistent
        [>....................] sync`ed:  0.1% (51188/51196)M

等資料同步完成以後,再檢視狀態(磁碟越大,資料格式化越久),可以發現節點已經實時狀態,且節點已經有了主次,節點主次是根據左primary、右secondary顯示。

# drbd-overview
  0:r0/0  Connected Primary/Secondary UpToDate/UpToDate C r-----

如果想要降級的話,只需要在對應的主節點上使用如下命令即可。

# drbdadm secondary r0

4)建立檔案系統(CentOS7預設使用xfs檔案系統)

檔案系統的掛載只能在Primary節點進行,因此,也只有在設定了主節點後才能對drbd裝置進行格式化:

# mkfs.ext4 /dev/drbd0
# mkdir /data
# mount /dev/drbd0 /data

5)正常切換Primary和Secondary節點

對主Primary/Secondary模型的drbd服務來講,在某個時刻只能有一個節點為Primary。因此,要切換兩個節點的角色,只能在先將原有的Primary節點設定為Secondary後,才能原來的Secondary節點設定為Primary。

node1
# cp -r /etc/drbd.* /data/drbd 
# umount /data/drbd
# drbdadm secondary r0

這裡需要先把primary節點變更為secondary節點,如果不執行這個命令,直接在備用節點執行切換到主節點的命令,會報錯:

0: State change failed: (-1) Multiple primaries not allowed by config
Command ‘drbdsetup-84 primary 0′ terminated with exit code 11

檢視狀態:

# drbd-overview
  0:r0  Connected Secondary/Secondary UpToDate/UpToDate C r----
node2
# drbdadm primary r0
# drbd-overview
  0:r0 Connected Primary/Secondary UpToDate/UpToDate C r----
# mkdir /data/drbd -p
# mount /dev/drbd0 /data/drbd

使用下面的命令檢視在此前在主節點上覆制至此裝置的檔案是否存在。

# ls /data/drbd

至此,DRBD主從模型實驗完成,但是真正上生產還需要多多測試,另外需要對drbd各個引數要熟悉,特別是效能調優引數,具體看官方文件。


相關文章