MySQL+DRBD+heartbeat
概述: DRBD 一、DRBD簡介 DRBD的全稱爲:Distributed ReplicatedBlock Device(DRBD)分佈式塊設備複製,DRBD是由內核模塊和相關腳本而構成,用以構建高可用性的集羣。其實現方式是通過網絡來鏡像整個設備。你可以把它看作是一種網絡RAID。它允許用戶在遠程機器上建立一個本地塊設備的實時鏡像。 二、DRBD工作原理 (DRBD Primary)負責接收數據,把數據寫到本地磁盤併發送給另一臺主機(DRBD Secondary)。另一個主機再將數據存到自己的磁盤中。目前,DRBD每次只允許對一個節點進行讀寫訪問,但這對於通常的故障切換高可用集羣來說已經足夠用了。有可能以後的版本支持兩個節點進行讀寫存取。 三、DRBD與HA的關係 一個DRBD系統由兩個節點構成,與HA集羣類似,也有主節點和備用節點之分,在帶有主要設備的節點上,應用程序和操作系統可以運行和訪問DRBD設備(/dev/drbd*)。在主節點寫入的數據通過DRBD設備存儲到主節點的磁盤設備中,同時,這個數據也會自動發送到備用節點對應的DRBD設備,最終寫入備用節點的磁盤設備上,在備用節點上,DRBD只是將數據從DRBD設備寫入到備用節點的磁盤中。現在大部分的高可用性集羣都會使用共享存儲,而DRBD也可以作爲一個共享存儲設備,使用DRBD不需要太多的硬件的投資。因爲它在TCP/IP網絡中運行,所以,利用DRBD作爲共享存儲設備,要節約很多成本,因爲價格要比專用的存儲網絡便宜很多;其性能與穩定性方面也不錯。 四、DRBD複製模式 協議A: 異步複製協議。一旦本地磁盤寫入已經完成,數據包已在發送隊列中,則寫被認爲是完成的。在一個節點發生故障時,可能發生數據丟失,因爲被寫入到遠程節點上的數據可能仍在發送隊列。儘管,在故障轉移節點上的數據是一致的,但沒有及時更新。這通常是用於地理上分開的節點 協議B: 內存同步(半同步)複製協議。一旦本地磁盤寫入已完成且複製數據包達到了對等節點則認爲寫在主節點上被認爲是完成的。數據丟失可能發生在參加的兩個節點同時故障的情況下,因爲在傳輸中的數據可能不會被提交到磁盤 協議C: 同步複製協議。只有在本地和遠程節點的磁盤已經確認了寫操作完成,寫才被認爲完成。沒有任何數據丟失,所以這是一個羣集節點的流行模式,但I / O吞吐量依賴於網絡帶寬 一般使用協議C,但選擇C協議將影響流量,從而影響網絡時延。爲了數據可靠性,我們在生產環境使用時須慎重選項使用哪一種協議 Heartbeat 一、heartbeat簡介 Heartbeat是Linux-HA工程的一個組件,自1999年開始到現在,發佈了衆多版本,是目前開源Linux-HA項目最成功的一個例子,在行業內得到了廣泛的應用,這裏分析的是2007年1月18日發佈的版本2.0.8。 隨着Linux在關鍵行業應用的逐漸增多,它必將提供一些原來由IBM和SUN這樣的大型商業公司所提供的服務,這些商業公司所提供的服務都有一個關鍵特性,就是高可用集羣。 二、heartbeat工作原理 heartbeat最核心的包括兩個部分,心跳監測部分和資源接管部分,心跳監測可以通過網絡鏈路和串口進行,而且支持冗餘鏈路,它們之間相互發送報文來告訴對方自己當前的狀態,如果在指定的時間內未收到對方發送的報文,那麼就認爲對方失效,這時需啓動資源接管模塊來接管運行在對方主機上的資源或者服務。 三、高可用集羣 高可用集羣是指一組通過硬件和軟件連接起來的獨立計算機,它們在用戶面前表現爲一個單一系統,在這樣的一組計算機系統內部的一個或者多個節點停止工作,服務會從故障節點切換到正常工作的節點上運行,不會引起服務中斷。從這個定義可以看出,集羣必須檢測節點和服務何時失效,何時恢復爲可用。這個任務通常由一組被稱爲“心跳”的代碼完成。在Linux-HA裏這個功能由一個叫做heartbeat的程序完成。 環境描述: 操作系統 IP地址 主機名 軟件包列表 CentOS6.6-x86_64 192.168.200.101 server-1 DRBD、heartbeat、mysql CentOS6.6-x86_64 192.168.200.102 server-2 DRBD、heartbeat、mysql 配置過程: 安裝前準備配置: 配置所有機器: [root@bogon ~]# fdisk /dev/sdb(主從都要配置,不需要格式化) Command (m for help): n Command action e extended p primary partition (1-4) P Partition number (1-4): 1 Last cylinder, +cylinders or +size{K,M,G} (1-2610, default 2610): +10G Command (m for help): w [root@server-1 ~]# partprobe /dev/sdb [root@bogon ~]# vim /etc/sysconfig/network 2 HOSTNAME=server-1 [root@bogon ~]# hostname server-1(從主機改爲server-2) [root@bogon ~]# bash [root@server-1 ~]# vim /etc/hosts 3 192.168.0.200 server-1 4 192.168.0.201 server-2 [root@server-1 ~]# service iptables stop [root@server-1 ~]# setenforce 0 Heartbeat安裝: 主從都需要安裝 [root@server-1 ~]# yum -y install perl-TimeDate cluster-glue-libs kernel-develkernel-headers flex [root@server-1 ~]# rpm -ivh cluster-glue-1.0.5-6.el6.x86_64.rpm [root@server-1 ~]# yum -y install heartbeat 安裝配置DRBD: 主從都需要安裝 [root@server-1 ~]# wget http://oss.linbit.com/drbd/8.4/drbd-8.4.3.tar.gz [root@server-1 ~]# tar xf drbd-8.4.3.tar.gz [root@server-1 ~]# cd drbd-8.4.3 [[email protected]]#./configure --prefix=/usr/local/drbd--with-km --with-heartbeat [[email protected]]# makeKDIR=/usr/src/kernels/2.6.32-642.el6.x86_64/ && make && makeinstall [[email protected]]# mkdir -p /usr/local/drbd/var/run/drbd [[email protected]]# cp /usr/local/drbd/etc/rc.d/init.d/drbd/etc/rc.d/init.d/ [[email protected]]# chkconfig --add drbd [[email protected]]# cd drbd [root@server-1 drbd]# make clean [root@server-1 drbd]# make KDIR=/usr/src/kernels/2.6.32-642.el6.x86_64/ [root@server-1 drbd]# cp drbd.ko /lib/modules/2.6.32-642.el6.x86_64/kernel/lib/ [root@server-1 drbd]# depmod [root@server-1 drbd]# cp -R /usr/local/drbd/etc/ha.d/resource.d/*/etc/ha.d/resource.d/ [root@server-1 drbd]# cd /usr/local/drbd/etc/drbd.d/ [root@server-1 drbd]# cat /usr/local/drbd/etc/drbd.conf # You can find an examplein /usr/share/doc/drbd.../drbd.conf.example include"drbd.d/global_common.conf"; include"drbd.d/*.res"; //此目錄下所有以.res結尾的都爲資源文件 配置global_common.conf文件(主從一致) [root@server-1 drbd.d]# vim global_common.conf global { usage-count yes; //是否對使用信息作統計,默認爲yes } common { startup { wfc-timeout 120; //等待連接的超時時間 degr-wfc-timeout 120; } disk { on-io-error detach; //當IO出現錯誤時執行的動作 } net { protocol C; //複製模式爲第3種 } } 配置資源文件(主從一致) [root@server-1 drbd.d]# vim r0.res resource r0 { //r0資源名稱 on server-1 { device /dev/drbd0; //邏輯設備路徑 disk /dev/sdb1; //物理設備 address 192.168.0.200:7788; //主節點 meta-disk internal; } on server-2 { device /dev/drbd0; disk /dev/sdb1; address 192.168.0.201:7788; //備節點 meta-disk internal; } } 創建元數據(兩個節點上操作) [[email protected]]# modprobedrbd [root@server-1 drbd.d]# dd if=/dev/zero bs=1M count=1 of=/dev/sdb1 [root@server-1 drbd.d]# drbdadm create-md r0 New drbd meta data blocksuccessfully created. 啓動DRBD(主從節點都要執行) [root@server-1 drbd.d]# /etc/init.d/drbd start Starting DRBD resources: [ create res: r0 prepare disk: r0 adjust disk: r0 adjust net: r0 ] ........ [root@server-1 drbd.d]# netstat -anpt | grep 7788 tcp 0 0 192.168.0.200:35654 192.168.0.201:7788 ESTABLISHED - tcp 0 0 192.168.0.200:7788 192.168.0.201:33034 ESTABLISHED - 手動驗證主從切換: 初始化網絡磁盤(主節點上執行) [root@server-1 drbd.d]# drbdadm -- --overwrite-data-of-peer primary r0 [root@server-1 drbd.d]# watch -n 2 cat /proc/drbd 2秒刷新一次 version: 8.4.3(api:1/proto:86-101) GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by root@bogon, 2016-12-0413:39:22 0: cs:SyncSource ro:Primary/Secondaryds:UpToDate/Inconsistent C r----- ns:116024 nr:0 dw:0 dr:123552 al:0 bm:7lo:0 pe:1 ua:7 ap:0 ep:1 wo:f oos:10374340 [>....................] sync'ed: 1.2% (10128/ 數據同步測試(主節點上操作前6步驟,次節點上操作後三步驟) [root@server-1 drbd.d]# mkfs.ext4 /dev/drbd0 [root@server-1 drbd.d]# mkdir /mysqldata [root@server-1 drbd.d]# mount /dev/drbd0 /mysqldata [root@server-1 drbd.d]# hostname > /mysqldata/file //建立測試文件 [root@server-1 ~]# umount /dev/drbd0 [root@server-1 ~]# drbdadm secondary r0 //主降爲次 [root@server-2 drbd.d]# drbdadm primary r0 //次升爲主 [root@server-2 drbd.d]# mount /dev/drbd0 /mysqldata [root@server-2 drbd.d]# ls /mysqldata //在備節點上查看數據 file lost+found //可以看到創建的文件 安裝MySQL: 更改Mysql數據庫的存儲位置爲共享目錄(主從都要執行) [root@server-1 ~]# yum -yinstall mysql mysql-server [root@server-1 ~]# vim/etc/my.cnf 2 datadir=/mysqldata/mysql [root@server-1 ~]# chown-R mysql.mysql /mysqldata [root@server-1 ]#chkconfig mysqld off [root@server-1 ~]#/etc/init.d/mysqld start 注意此時我們修改了數據目錄和其屬主和權限,有時會因爲此操作導致數據庫無法啓動,解決方法,一,查看你的selinux是否處於打開狀態,將其關閉。二,/etc/apparmor.d/usr.sbin.mysqld文件中,有兩行內容規定了mysql使用數據文件的路徑權限,改掉即可,重啓/etc/init.d/apparmor restart。 進行數據庫測試 因爲此前的操作,現在把server-2節點降爲次 [root@server-2 ~]# umount /dev/drbd0 [root@server-2 ~]# drbdadm secondary r0 把server-1升爲主節點 [root@server-1 ~]# drbdadm primary r0 [root@server-1 ~]# mount /dev/drbd0 /mysqldata 在server-1上創建一個庫名爲accp,然後主降爲備,把server-2升爲主查看庫有沒有同步。 [root@server-1 ~]# service mysqld stop //server-1的操作 [root@server-1 ~]# umount /dev/drbd0 //server-1的操作 [root@server-1 ~]# drbdadm secondary r0 //server-1的操作 [root@server-2 drbd.d]# drbdadm primary r0 //server-2的操作 [root@server-2 drbd.d]# mount /dev/drbd0 /mysqldata //server-2的操作 [root@server-2 drbd.d]# service mysqld start //server-2的操作 [root@server-2 drbd.d]# ls /mysqldata/mysql/ //server-2的操作 accp ibdata1 ib_logfile0 ib_logfile1 mysql test 配置heartbeat: 一、配置ha.cf文件(主從大體一致) [root@server-1 ~]# cd /usr/share/doc/heartbeat-3.0.4/ [[email protected]]# cp ha.cf authkeys haresources/etc/ha.d/ [[email protected]]# cd /etc/ha.d/ [root@server-1 ha.d]# vim ha.cf 29 logfile /var/log/ha-log 34 logfacility local0 48 keepalive 2 //多長時間檢測一次 56 deadtime 10 //連續多長時間聯繫不上後認爲對方掛掉(秒) 61 warntime 5 //連續多長時間聯繫不上開始警告提示 71 initdead 100 //主要是給重啓後預留的一段忽略時間 76 udpport 694 //UDP端口 121 ucast eth0192.168.200.102 //填寫對方IP(主從的差異點) 157 auto_failback on //節點修復後是否切換回來 211 node server-1 //節點名稱 212 node server-2 //節點名稱 253 respawn hacluster/usr/lib64/heartbeat/ipfail //控制IP切換的程序x86_64爲應該寫lib64 二、配置haresources文件(主從一致) [root@server-1 ha.d]# vim haresources server-1IPaddr::192.168.200.50/24/eth0:0 drbddisk::r0 Filesystem::/dev/drbd0::/mysqldata::ext4 mysqld [root@server-1 ha.d]# ln -s /etc/init.d/mysqld /etc/ha.d/resource.d/mysqld 三、配置authkeys文件(主從一致) [root@server-1 ha.d]# vim authkeys 23 auth 1 24 1 crc [root@server-1 ha.d]# chmod 600 authkeys 驗證: 主從節點啓動heartbeat [root@server-1 ha.d]# service heartbeat start 查看主節點VIP是否存在 [root@server-1 ha.d]# ip a inet 192.168.200.50/24 brd192.168.200.255 scope global secondary eth0:0 驗證:先停掉server-1上的heartbeat服務,查看VIP是否能轉移 此時server-2的mysql服務是關閉的 [root@server-2 ha.d]# mysqladmin -uroot ping //備節點操作 mysqladmin: connect to serverat 'localhost' failed error: 'Can't connect tolocal MySQL server through socket '/var/lib/mysql/mysql.sock' (2)' Check that mysqld isrunning and that the socket: '/var/lib/mysql/mysql.sock' exists! [root@server-1 ha.d]# service heartbeat stop //主節點操作 Stopping High-Availabilityservices: Done. [root@server-2 ha.d]# ip a //備節點操作 inet 192.168.0.50/24 brd192.168.0.255 scope global secondary eth0:0 [root@server-2 ha.d]#mysqladmin -uroot ping //備節點操作,發現mysql隨之啓動 Mysqld is alive 此時還不具備停掉mysql後VIP漂移的功能,需要添加腳本實現,當發現mysql服務出現掛掉,就停掉heartbeat服務,實現VIP轉移(雙方都要在後臺執行) [root@server-1 ~]# vimchk_mysql.sh #!/bin/bash mysql="/etc/init.d/mysqld" mysqlpid=$(ps -C mysqld--no-header | wc -l) if [ $mysqlpid -eq 0];then $mysql start sleep 3 mysqlpid=$(ps -C mysqld --no-header |wc -l) if [ $mysqlpid -eq 0 ];then /etc/init.d/heartbeat stop echo "heartbeatstopped,please check your mysql !" | tee -a /var/log/messages fi fi