DRBD分布式复制块设备及DRBD高可用配置
DRBD,顾名思义,全称为Distributed Replicated Block Device(DRBD)是一个用软件实现的、无共享的、服务器之间镜像块设备内容的存储复制解决方案。 DRBD Logo DRBD Logo 数据镜像:实时、透明、同步(所有服务器都成功后返回)、异步(本地服务器成功后返回)
主要目的是将两台主机的两个设备能够做成类似于RAID1对接硬盘的效果一样,但是可以跨越主机的 ,所以也被称为分布式的RAID
为什么使用DRBD
以NFS服务为例,当前端都是高可用或冗余,但是后端只有NFS服务为其做共享存储,那么存储本身属于单点故障,如果其节点一旦故障,可导致整个架构的瘫痪,所以这时需要对所谓的NFS做高可用集群
为了高可用的目的在两个NFS中提供共享存储,而后在NFS中输出出去
由此在这基础上如果不使用NFS则可以直接提供一个共享存储
那共享存储的方案无非有以下几种:
・DAS
・NAS
・SAN
・DLM:Distributed Lock M
一般来讲编译的时候需要支持分布式锁管理器或者后期编译内核
就算使用了分布式锁管理机制(DLM)使用一般文件系统,比如ext3/4 等亦然不可以,因为其并不支持这种锁机制,也就是说必须使用专用的文件系统
集群文件系统类型
常见的集群文件系统类型有:
・GFS : Global File System #在红帽4上流行的是GFS 红帽5上两者都支持 6上仅支持GFS2
・OCFS2: Oracle Cluster File System
由此必须使用这种共享存储才可以
而一般来讲能够实现存储机制对象像DAS NAS SAN 代价都非常的高,对一些小型企业来讲可望不可即
那么这时,DRBD就派上用场了:
配置DRBD前提,只要2个空间分区两个空间大小一样即可,而后能够实现在2个节点内核当中启动一个内核模块"DRBD"模块 这个模块能够监听在套接字上,这样之后在某个节点中的某个进程试图在drbd的分区中写入数据的时候,这个数据一定会流进内核DRBD模块之后内核会将数据复制一份并通过本地的tcp/ip协议栈发往另外一个节点的DRBD进程,其收到请求后将数据默默的存放在本地的DRBD的存储空间中 从而达到一致,所以当写入数据的时候首先会流进本地内核中的drbd模块,其会被分为2个数据流 一个继续往下存储一个则通过网络发送给另外的DRBD节点从而达成数据的冗余
在drbd 主节点被称为 primary 备节点被称为secondary
DRBD主备之间的健康检查机制
可以将其做成高可用服务资源,将其定义为主从类型,任何时候主节点挂掉,自动将备节点提升为primary
如果不想让其称为primary的话可以将其demote降级为secondeary,而原来的secondeary则提升为primary
这一切都需要依赖高可用集群服务来完成
DRBD是在内核中工作的,DRBD是内核模块,但磁盘上有N个分区,思考到底是哪个分区是DRBD的分区:
需要依赖于用户空间的工具来完成
drbdadm
drbdsetup
对于drbd来讲数据是从一个节点从而复制到另外一个节点的,一般来说,当一个进程发起写请求的时候,会发起系统调用,
为了提高用户的体验,内核通常在内核内存中完成了写操作会通知用户操作完成,需要过段时间才会从内核中同步至磁盘中去
那一旦在drbd中写数据的话,为了保证写入完整,有三种方式可以实现:
通过tcp/ip协议栈封装成报文,并交给TCP/IP发送缓冲区,接着网卡通过DMA机制依次将报文发送出去
・A模式:协议模型,当用户存放的报文已经被送到本地的协议缓冲区里,至于已经被网卡发送过的,则不会去管理
意味着只要发往本地的发送缓冲则OK ,但并不保证数据准确无误的送往至对方节点中
・B模式:半同步模式。首先将数据发送至本地的发送缓冲区,其次对方节点网卡收到报文,再次存入内核空间中,至于是否同步下来则不会考虑
・C模式:默认模式,同步模式,考虑对方是否送达,考虑是否完全同步
#A表示到达自己的发送缓冲
#B表示到达对方的接受缓冲
#C表示对方已经完全存放
如果不能接受数据有所损失则可以使用C模式 ,如果在性能或数据丢失一点也无所谓的话则使用A模式。一般默认的选项是C模式
dual primary node(双主模型)
为了避免双方挂载同时间写入造成的冲突
前提是只能是在高可用集群中使用RDBD并确定使用分布式文件锁
因此 当一个节点进行写操作的话,持有锁信息,右节点会收到,因此右节点不会进行写,因此这种锁只有集群文件系统才可以支持
所以注意的前提是:
・1 只有高可用环境中使用DRBD
・2 要启用分布式文件锁功能
・3 将DRBD格式化成集群系统
因此跟我们共享文件系统是一样的,而且是块文件系统,必须是文件系统,必须使用的是底层文件信息通道,必须格式化成集群文件系统
才可以实现双主模型
DRBD工作图解
・首先通过内核的系统调文件系统接口提交给文件系统(buffer cache)
・buffer cache维持了缓冲区
・缓存区交给磁盘调度器,调度器主要讲多个连续的写操作合并至一个,以提高磁盘性能,尤其对机械硬盘起到作用,但对ssd硬盘通常作用不大
・而后由dis driver真正发起磁盘寻道等操作,真正将数据存储下来
・而DRDB又工作在buffer cache 和scheduler之间,所以在实现合并之前,每一个在buffer cache中完成的写操作通过tcp/ip协议栈发往网卡的驱动程序由网卡驱动程序发往另一个网卡,网卡对其解码之后发给TCP/IP协议栈
・对方TCP/IP协议栈发现是工作在DRDB内核模块中的报文,将数据转发给DRBD,DRBD写在本地 从而达到数据一致性
如果DRBD工作正常的时候双方是同步的,万一备节点挂了,以后想让其重新上线那么主节点要比备节点数据“晚”很长时间,如果这时备节点上线了,需要将大量数据复制到其本地,而主节点还需要将数据从自己的磁盘中读取出来,完成同步,这时候网络带宽的负载是非常大的,服务性能也会非常的差
配置DRBD
配置DRBD本身并不依赖于其他高可用服务,可以完全手动,只有想让其自动完成提供或降级才需要依赖高可用集群套件
一般来讲DRBD可以与heartbeat 、cman 、crorsync等结合使用
接下来不使用高可用集群,深入浅出的来配置DRBD
规划如下:
服务器IP地址 |
服务器角色 |
10.0.10.61 |
Node1 |
10.0.10.62 |
Node2 |
配置时间同步
[root@node1 ~]#ntpdate time.windows.com
安装DRBD
要下载与内核版本完全匹配的软件包
[root@node1 ~]#uname -a
Linux node2 2.6.32
可在rpmfind中找到对应的包名,如果内核升级相应的,drbd就要使用升级后对应内核的版本
[root@node1 tools]#ls
drbd-8.4.3-33.el6.x86_64.rpm
drbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm
#以上2个包基本没有任何依赖关系
在本地安装即可
[root@node1tools]# rpm -ivh *.rpm
要配置一个drbd设备要准备一个资源而资源所需的属性都有如下:
・资源名称
・块设备,分区并空间大小必须一致
假如两边都创建2G的分区,不要太大,尤其是两个节点直接同步的时候,同步的时间会很长
重新建立分区
以sdb为例,创建一新分区,大小为2G空间,双节点都执行以下操作
[root@node2 ~]#fdisk /dev/sdb
[root@node2 ~]#fdisk -l /dev/sdb
#分区步骤略过
Disk /dev/sdb: 2147MB, 2147483648 bytes
255 heads, 63sectors/track, 261 cylinders
Units = cylindersof 16065 * 512 = 8225280 bytes
Sector size(logical/physical): 512 bytes / 512 bytes
I/O size(minimum/optimal): 512 bytes / 512 bytes
Disk identifier:0xad6e184f
Device Boot Start End Blocks Id System
/dev/sdb1 1 261 2096451 83 Linux
使分区
[root@node1~]# kpartx -a /dev/sdb
配置DRBD
默认DRBD的安装路径是在/etc/drbd.d/下
[root@node1 ~]# cd/etc/drbd.d/
[root@node1 drbd.d]# ls
global_common.conf
主配置文件在/etc下,如下所示
[[email protected]]# cat /etc/drbd.conf
# You can find an example in /usr/share/doc/drbd.../drbd.conf.example
include "drbd.d/global_common.conf"; #调用global_common.conf文件
include"drbd.d/*.res"; #所有以.res结尾的文件
所以我们不用管它继续我们的配置
配置global-common.conf
[root@node1 ~]# cd/etc/drbd.d/
[[email protected]]# cp global_common.conf global_common.conf.bak
修改global-common.conf
[[email protected]]# cat global_common.conf
global {
usage-count no; #统计drbd的使用
# minor-count dialog-refreshdisable-ip-verification
}
common {
protocol 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 {
#wfc-timeout 120;
#degr-wfc-timeout 120;
}
disk {
on-io-error detach;
#fencing resource-only;
}
net {
cram-hmac-alg "sha1";
shared-secret "mydrbdlab"; #随机子字符串,认证需要
}
syncer {
rate 1000M;
}
}
紧接着定义第一个资源
创建mydata.res,文件名任意,但后缀名必须要以res结尾,内容如下
resource mydata {
#以下为全局配置,默认都是使用的drbd0设备文件,以及sdb1分区
device /dev/drbd0;
disk /dev/sdb1;
on node1 #定义资源1
address 10.0.10.61:7789; #监听在网络地址的哪个端口上
meta-disk internal; # DRBD是有元数据的,为了保证磁盘镜像是完整的它也需要镜像元数据,其元数据默认也是放在磁盘分区上的,存放在当前磁盘上的参数为internal
}
on node2 {
address 10.0.10.62:7789;
meta-disk internal;
}
}
当资源定义完毕要将每个节点的镜像都进行同步
但是两端的配置文件都要一致
[[email protected]]# scp * root@node2:/etc/drbd.d/
global_common.conf 100% 1403 1.4KB/s 00:00
global_common.conf.bak 100% 1836 1.8KB/s 00:00
mydata.res 100% 215 0.2KB/s 00:00
初始化资源
配置完成,接下来该初始化资源了
在双方节点分别执行 drbdadm create-md mydata命令进行初始化
[[email protected]]# drbdadm create-md mydata
Writing metadata...
initializingactivity log
NOT initializingbitmap
lk_bdev_save(/var/lib/drbd/drbd-minor-0.lkbd)failed: No such file or directory
New drbd meta datablock successfully created.
lk_bdev_save(/var/lib/drbd/drbd-minor-0.lkbd)failed: No such file or directory
[[email protected]]# echo $?
0
警告信息可以忽略不计
双方都启动DRBD服务并观察
[[email protected]]# /etc/init.d/drbd start
查看运行状态
[[email protected]]# /etc/init.d/drbd status
drbd driver loadedOK; device status:
version: 8.4.3(api:1/proto:86-101)
GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-05-27 04:30:21
m:res cs ro ds p mounted fstype
0:mydata Connected Secondary/Secondary Diskless/Diskless C
一旦启动了在proc目录中肯定会生成drbd文件的,如下所示
[[email protected]]# ls /proc/drbd
/proc/drbd
我们来cat一下查看
[root@node1 ~]# cat/proc/drbd
version: 8.4.3(api:1/proto:86-101)
GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-05-27 04:30:21
0: cs:Connected ro:Secondary/Secondaryds:Inconsistent/Inconsistent C r-----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0ua:0 ap:0 ep:1 wo:f oos:2104376
发现双方都是从节点,我们需要手动将其中一节点提升为主节点
Inconsistent 表示双方还没有同步数据
我们需要将一节点升为主节点而后就可以自动同步更新数据了
[[email protected]]# drbdadm primary --force mydata
[root@node1 ~]#watch -n1 'cat /proc/drbd'
version: 8.4.3(api:1/proto:86-101)
GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-05-27 04:30:21
0: cs:SyncSource ro:Primary/Secondaryds:UpToDate/Inconsistent C r---n- #
ns:127728 nr:0 dw:0 dr:134816 al:0 bm:7lo:0 pe:2 ua:7 ap:0 ep:1 wo:f oos:1978424
[>...................]sync'ed: 6.1% (1978424/2104376)K
finish: 0:07:55speed: 4,140 (4,340) K/sec
Primary/Secondary 可以发现我们当前节点已经是主节点了
UpToDate/Inconsistent 状态是本机正在更新,状态非一致的
等数据一致之后便可以格式化DRBD分区了
[root@node1 ~]# cat/proc/drbd
version: 8.4.3(api:1/proto:86-101)
GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-05-27 04:30:21
0: cs:Connected ro:Primary/Secondaryds:UpToDate/UpToDate C r-----
ns:2104376 nr:0 dw:0 dr:2105048 al:0 bm:129lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
数据已同步完成,于是我们只在主节点格式化分区
[[email protected]]# mke2fs -t ext4 /dev/drbd0
挂载测试
[root@node1 ~]#mount /dev/drbd0 /mnt/
[root@node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 19G 2.7G 16G 15% /
tmpfs 499M 0 499M 0% /dev/shm
/dev/sda1 291M 33M 243M 12% /boot
/dev/drbd0 2.0G 68M 1.9G 4% /mnt
向其拷贝文件并查看分区是否可写
[[email protected]]# cp /etc/passwd /mnt/
[root@node1 drbd.d]# ls /mnt/
lost+found passwd
测试是否同步
手动将其降级并查看
注意的是如果升级或降级必须是主的一方先降级然后才能升级
取消挂载
[root@node1 ~]#umount /mnt/
使其主节点降级为备节点
[root@node1 ~]# drbdadmsecondary mydata
使用drbd-overview命令查看其状态
[root@node1 ~]#drbd-overview
0:mydata/0 Connected Secondary/Secondary UpToDate/UpToDate C r-----
切换至node2,并将node2提升为主节点
[root@node2 ~]# drbdadm primary mydata
[root@node2 ~]#drbd-overview
0:mydata/0 Connected Primary/Secondary UpToDate/UpToDate C r-----
挂载目录并查看之前拷贝的文件是否存在
[root@node2 ~]# ll/mnt/
total 20
drwx------. 2 rootroot 16384 May 26 16:37 lost+found
-rw-r--r--. 1 rootroot 1678 May 26 16:41 passwd
可以看到,已经将其切换成功,并达到数据一致的效果,但是如果某节点出现故障我们只能手动去切换节点未免有点太麻烦了,这时可以将其部署为高可用集群为我们省去不少麻烦
基于Corosync+Packmaker+DRBD实现高可用集群
想要实现自动的角色转换,要借助于高可用底层信息通道来实现以及高可用资源管理器来实现
一般来讲DRBD通常来说是双节点,可以是一主一从 也可以是双主
配置DRBD高可用
将其都降级为从节点
[root@node1 ~]#drbdadm secondary mydata
确保无误
[root@node1 ~]#drbd-overview
0:mydata/0 Connected Secondary/Secondary UpToDate/UpToDate Cr-----
确保数据一致的,接下来停止drbd服务,因为如果定义成高可用集群 一定是不能提前开启的
#定义高可用集群之前 首先需要搭建好drbd 并且在双节点上都需要手动升级或降级,确保无误才能继续
[root@node1 ~]#/etc/init.d/drbd stop
确保双节点的drbd都不会开机启动
[root@node1 ~]#chkconfig drbd off
配置corosync
配置安装corosync请借鉴之前文章
双方都同时启动corosync
[root@node1 ~]#/etc/init.d/corosync start
查看当前集群的配置信息,确保已经配置全局属性参数为两节点集群所适用:
[root@node1 ~]# crm configure show
node node1 \
attributesstandby=off
node node2 \
attributesstandby=off
property cib-bootstrap-options: \
dc-version=1.1.10-14.el6_5.3-368c726\
cluster-infrastructure="classicopenais (with plugin)" \
expected-quorum-votes=2\
stonith-enabled=false\
last-lrm-refresh=1400510232\
no-quorum-policy=ignore
在如上输出的信息中,请确保有stonith-enabled和no-quorum-policy出现且其值与如上输出信息中相同。否则,可以分别使用如下命令进行配置:
# crm configure property stonith-enabled=false
# crm configure propertyno-quorum-policy=ignore
定义资源
drbd需要同时运行在两个节点上,但只能有一个节点(primary/secondary模型)是Master,而另一个节点为Slave;因此,它是一种比较特殊的集群资源,其资源类型为多态(Multi-state)clone类型,即主机节点有Master和Slave之分,且要求服务刚启动时两个节点都处于slave状态
[root@node1 ~]# crm
crm(live)# configure
crm(live)configure# primitive mysql_drbdocf:linbit:drbd params drbd_resource=mydata op monitor role=Master interval=10timeout=20 op monitor role=Slave interval=20 timeout=20 op start timeout=240 opstop timeout=100
crm(live)configure# verify
参数说明:
#primitive mysql_drbd #定义资源名称
#op monitor role=Master #指明监控master
#interval=50s #多长时间监控一次
#timeout=30s #超时时间多少
#op monitor role=Slave #监控slave
#interval=60s #监控时隔
#timeout=30s #超时时间
#检测时间最好定义为其默认值
定义主从资源
crm(live)configure# ms ms_mysql_drbd mysql_drbd meta master-max="1"master-node-max="1" clone-max="2"clone-node-max="1" notify="true"
crm(live)configure# verify
参数说明:
#ms跟名称,明确说明将哪个资源作为主从资源 而后跟meta参数
#将mysql_drbd做为主从资源
#master-max="1 #主资源有1个
#master-node-max="1" #node节点有1个
#clone-max="2 #最多可克隆2个资源
#clone-node-max="1" #每个副本节点最多运行1个
#notify="true" #当一个新的副本加入进来的时候是否通知其他副本
确认无误保存规则
crm(live)configure# commit
执行完成之后退出终端并查看其状态
crm(live)# status
Online: [ node1 node2 ]
#如下所示,目前启动了2个副本,主为node1 从为node2
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node1 ]
Slaves: [ node2 ]
如果将node1更改为备节点,并查看其会发生什么
[root@node1 ~]# pcs cluster standby node1
[root@node1 ~]# crm status
#中间略过#
Node node1: standby
Online: [ node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node2 ]
Stopped: [ node1 ]
可用看到,主为node2 ,但从未stoped 关闭状态,因为备节点是不能运行资源的
使用备节点重新上线,但处于unstandby模式
[root@node2 ~]# crm node unstandby
查看DRBD信息
[root@node2 ~]# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
GIT-hash:89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-05-27 04:30:21
0:cs:Connected ro:Secondary/Primary ds:UpToDate/UpToDate C r-----
ns:0 nr:0 dw:0 dr:0 al:0 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
使其自动挂载文件系统
文件系统挂载的节点必须要跟主从资源的主节点在一块
并定义次序:先将drb的主节点提升为主,完成之后才能挂载
首先需要有挂载的目录,这里我们是以mysql的路径为基准
创建路径
[root@node1 ~]# mkdir /mydata/
定义文件系统资源
定义文件系统资源之前首先来规划一下思路:
(1)定义资源类型为filesystem
(2)挂载的设备是drbd0
(3)挂载点是/mydata
(4)文件系统类型为ext4
[root@node1 ~]# crm configure
crm(live)configure# primitive mystoreocf:heartbeat:Filesystem params device="/dev/drbd0"directory="/mydata" fstype="ext4" op monitor interval=40timeout=40 op start timeout=60 op stop timeout=60
crm(live)configure# verify
定义排列约束和顺序约束
要先将主从资源的master 进行promote操作然后才能启动mystore的
定义顺序约束:
表示对方只有处于promote状态 其才能进行挂载
crm(live)configure# order colocationmystore_with_ms_mysql_drbd_master inf: mystore ms_mysql_drbd:Master
crm(live)configure# verify
crm(live)configure# commit
#mystore_with_ms_mysql_drbd_master mytore必须要跟ms_mysql_drbd的master在一块
#inf 表示无穷大
#mystorems_mysql_drbd:Master 表示mystore 跟 drbd的主资源在一起
定义次序
要先将主从资源的master 进行promote操作然后才能启动mystore的
定义顺序约束:
#表示对方只有处于promote状态 其才能进行挂载
crm(live)configure# orderms_mysql_drbd_before_mystore mandatory: ms_mysql_drbd:promote mystore:start
crm(live)configure# verify
crm(live)configure# commit
执行status查看
crm(live)configure# cd
crm(live)# status
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node2 ]
Slaves: [ node1 ]
mystore(ocf::heartbeat:Filesystem): Started node2
可见,mystore已然启动
查看是否被挂载
[root@node2 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 1.6G 17G 9% /
tmpfs 499M 37M 462M 8% /dev/shm
/dev/sda1 194M 28M 156M 16% /boot
/dev/drbd0 2.0G 68M 1.9G 4% /mydata
将node2更改为备节点,并在node1上查看是否自动挂载
[root@node1 ~]# crm status
Last updated: Tue May 27 16:11:47 2014
Last change: Tue May 27 16:11:44 2014 viacrm_attribute on node2
Stack: classic openais (with plugin)
Current DC: node2 - partition with quorum
Version: 1.1.10-14.el6_5.3-368c726
2 Nodes configured, 2 expected votes
3 Resources configured
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node1 ]
Slaves: [ node2 ]
mystore(ocf::heartbeat:Filesystem): Started node1
查看node1是否被挂载目录
[root@node1 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 19G 2.7G 16G 15% /
tmpfs 499M 22M 477M 5% /dev/shm
/dev/sda1 291M 33M 243M 12% /boot
/dev/drbd0 2.0G 68M 1.9G 4% /mydata
查看目录数据是否存在
[root@node1 ~]# ll /mydata/
total 24
-rw-r--r--. 1 root root 805May 27 13:17 fstab
drwx------. 2 root root 16384 May 26 16:37lost+found
-rw-r--r--. 1 root root 1678 May 26 16:41 passwd
再次测试
将node1更改为备节点,并在node2上查看资源是否被转移
[root@node1 ~]# crm node standby
[root@node1 ~]# crm node online
[root@node1 ~]# crm status
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node2 ]
Slaves: [ node1 ]
mystore(ocf::heartbeat:Filesystem): Started node2
切换至node2 查看数据是否存在
[root@node2 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 1.6G 17G 9% /
tmpfs 499M 37M 462M 8% /dev/shm
/dev/sda1 194M 28M 156M 16% /boot
/dev/drbd0 2.0G 68M 1.9G 4% /mydata
[root@node2 ~]# ls /mydata/
fstab lost+found passwd
实现高可用Mysql/MariaDB集群
假设此时我们期望将当前节点定义为高可用mysql集群,那么依赖drbd就可以实现数据一致了
那mysql应该运行在主节点而且还必须mystore启动之后mysql才可以启动
而且mysql启动服务的时候还必须要向外提供独立IP地址
双方都安装并配置MariaDB
[root@node1 ~]# tar xfmariadb-5.5.32-linux-x86_64.tar.gz -C/usr/local/
root@node2 ~]# cd /usr/local
查看其状态
[root@node1 ~]# crm status
Last updated: Tue May 27 21:56:33 2014
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node1 ]
Slaves: [ node2 ]
mystore(ocf::heartbeat:Filesystem): Started node1
当前主节点是node1,所以要在node1上做操作,千万不要弄反了
在双方节点都创建mysql用户
一定要让两边节点的用户id号统一,不然访问同一文件系统上的块节点不一样,用户名对应的也不一样了
root@node1 ~]# useradd -r -u 306 mysql
[root@node1 ~]# id mysql
uid=306(mysql) gid=306(mysql)groups=306(mysql)
切换至主节点创建数据存放的目录
[root@node1 ~]# mkdir /mydata/data
[root@node1 ~]# chown -R mysql.mysql /mydata/data/
[root@node1 ~]# ll -ld /mydata/data/
drwxr-xr-x. 2 mysql mysql 4096 May 27 21:59/mydata/data/
创建软链接,软链名称一定必须是mysql
[root@node1 ~]# cd /usr/local/
[root@node1 local]# ln -s mariadb-5.5.32-linux-x86_64mysql
[root@node1 local]# ll | grep mysql
lrwxrwxrwx. 1 root root 27 May 27 22:02mysql -> mariadb-5.5.32-linux-x86_64
授权目录
[root@node1 local]# chown -R root.mysql mysql/
初始化数据
[root@node1 mysql]# scripts/mysql_install_db--user=mysql --datadir=/mydata/data/
验证是否存在问题
[root@node1 mysql]# ll -lth /mydata/data/
total 32K
-rw-rw----. 1 mysql mysql 16K May 27 22:04 aria_log.00000001
-rw-rw----. 1 mysql mysql 52 May 27 22:04 aria_log_control
drwx------. 2 mysql mysql 4.0K May 27 22:04performance_schema
drwx------. 2 mysql root 4.0K May 27 22:04 mysql
drwx------. 2 mysql root 4.0K May 27 22:04 test
复制配置文件
[root@node1 mysql]# cp support-files/my-large.cnf /etc/my.cnf
[root@node1 mysql]# cpsupport-files/mysql.server /etc/init.d/mysqld
[root@node1 mysql]# chmod +x/etc/init.d/mysqld
修改配置文件
[root@node1 mysql]# vim /etc/my.cnf
#修改如下参数,如果没有则手动添加
thread_concurrency = 2
datadir = /mydata/data
innodb_file_per_table = 1
启动测试
[root@node1 mysql]# /etc/init.d/mysqld start
Starting MySQL......... [ OK ]
加入环境变量
[root@node1 mysql]# echo 'exportPATH=$PATH:/usr/local/mysql/bin' >>/etc/profile
[root@node1 mysql]# source /etc/profile
创建一远程用户方便之后的验证
[root@node1 mysql]# mysql
MariaDB [(none)]> grant all on *.* to 'test'@'%'IDENTIFIED by 'test';
Query OK, 0 rows affected (0.00 sec)
MariaDB [(none)]> flush privileges;
Query OK, 0 rows affected (0.00 sec)
接下来可以停止服务了而后将当前节点切换成备节点测试另外节点是否可以启动成功
[root@node1 mysql]# /etc/init.d/mysqld stop
切换至node2
[root@node2 local]# ln -smariadb-5.5.32-linux-x86_64 mysql
将node1的配置文件复制于node2
[root@node1mysql]# scp /etc/my.cnf node2:/etc/
[root@node1 mysql]# scp /etc/init.d/mysqldnode2:/etc/init.d/
/mydata/下面是空目录 不用创建目录更不用初始化,因为之前在node1上已经初始化完成
切换主备节点
[root@node1 ~]# /etc/init.d/mysqld stop
将node1下线并切换至备节点状态
[root@node1 ~]# crm node standby
[root@node1 ~]# crm node online
[root@node1 ~]# crm status
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node2 ]
Slaves: [ node1 ]
mystore(ocf::heartbeat:Filesystem): Started node2
在node2验证是否被挂载
[root@node2 ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 20G 2.6G 16G 15% /
tmpfs 499M 22M 477M 5% /dev/shm
/dev/sda1 194M 28M 156M 16% /boot
/dev/drbd0 2.0G 68M 1.9G 4% /mydata
启动测试
[root@node2 etc]# /etc/init.d/mysqld start
Starting MySQL.... SUCCESS!
定义VIP地址
定义之前,必须考虑几个问题:
(1)mysql必须要跟drbd主节点在一起
(2)定义vip,如果vip挂掉则自动重启
crm(live)configure# primitive myipocf:heartbeat:IPaddr params ip="10.0.10.100" op monitor interval=20timeout=20 on-fail=restart
crm(live)configure# verify
IP应该与mysql服务在一起,mysql服务而又要与mystore在一起,而mystore之前已经定义过了
定义mysqld服务
crm(live)configure# primitive myserverlsb:mysqld op monitor interval=20 timeout=20 on-fail=restart
crm(live)configure# verify
定义资源之间关系
myserver一定要与mystore在一起,并且mystore启动之后myserver才可以启动
myip还要与myserver在一起,而且myip启动后myserver才能启动
crm(live)configure# colocationmyserver_with_mystore inf: myserver mystore
crm(live)configure# verify
定义启动次序
crm(live)configure# ordermystore_before_myserver mandatory: mystore:start myserver:start
crm(live)configure# verify
定义IP地址与myserver在一起
crm(live)configure# ordermyip_before_myserver mandatory: myip myserver
检查语法,确保无误则保存资源
crm(live)configure# verify
crm(live)configure# commit
查看状态
crm(live)configure# cd
crm(live)# status
Online: [ node1 node2 ]
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node2 ]
Slaves: [ node1 ]
mystore(ocf::heartbeat:Filesystem): Started node2
myip (ocf::heartbeat:IPaddr): Startednode1
myserver(lsb:mysqld):Started node2
连接测试
尝试连接vip
[root@node2 ~]# mysql -utest -ptest-h10.0.10.100
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 11
Server version: 5.5.32-MariaDB-log MariaDBServer
Copyright (c) 2000, 2013, Oracle, MontyProgram Ab and others.
Type 'help;' or '\h' for help. Type '\c' toclear the current input statement.
MariaDB [(none)]>
以上,已连接成功
使资源转移并测试
[root@node2 ~]# crm node standby
[root@node2 ~]# crm node online
[root@node2 ~]# crm status
Online: [ node1 node2 ]
Master/Slave Set: ms_mysql_drbd [mysql_drbd]
Masters: [ node1 ]
Slaves: [ node2 ]
mystore(ocf::heartbeat:Filesystem): Started node1
myserver(lsb:mysqld):Started node1
myip (ocf::heartbeat:IPaddr): Started node1
测试连接是否成功,如下所示
[root@node2 ~]# mysql -utest -p -h10.0.10.100
Enter password:
Welcome to the MariaDB monitor. Commands end with ; or \g.
Your MariaDB connection id is 1
Server version: 5.5.32-MariaDB-log MariaDBServer
Copyright (c) 2000, 2013, Oracle, MontyProgram Ab and others.
Type 'help;' or '\h' for help. Type '\c' toclear the current input statement.
MariaDB [(none)]>
总结:
・启动顺序依次为myip -->myserver -->mysqldrbd -->ms_mysql_drbd 并挂载mystore
・在其5个资源中ms_mysql_drbd是核心,所有的一切都是围绕其工作的
・可以将其定义为组的模式 这样剩下的就是启动顺序的问题了
脑裂的解决办法
之前冷重启了一次,由于没正常关闭服务,而再次启动服务的时候导致数据不同步,经查看日志,断定是脑裂问题
[root@node1 ~]# tail /var/log/messages
May 28 12:38:18 node1 kernel: block drbd0: helper command: /sbin/drbdadminitial-split-brain minor-0 exit code 0 (0x0)
May 28 12:38:18 node1 kernel: block drbd0: Split-Brain detected but unresolved,dropping connection!
May 28 12:38:18 node1 kernel: block drbd0: helper command: /sbin/drbdadmsplit-brain minor-0
May 28 12:38:18 node1 kernel: block drbd0: helper command: /sbin/drbdadmsplit-brain minor-0 exit code 0 (0x0)
May 28 12:38:18 node1 kernel: d-con mydata: conn( NetworkFailure ->Disconnecting )
May 28 12:38:18 node1 kernel: d-con mydata: error receiving ReportState, e: -5l: 0!
May 28 12:38:18 node1 kernel: d-con mydata: Connection closed
May 28 12:38:18 node1 kernel: d-con mydata: conn( Disconnecting ->StandAlone )
May 28 12:38:18 node1 kernel: d-con mydata: receiver terminated
May 28 12:38:18 node1 kernel: d-con mydata: Terminating drbd_r_mydata
首先要使得数据同步,必然要将高可用集群服务停止才可以进行下一步操作
双方停止服务
[root@node2 ~]# /etc/init.d/corosync stop
将node2设置为从节点并丢弃资源数据
[root@node2 ~]# drbd-overview
0:mydata/0 StandAlone Secondary/UnknownUpToDate/DUnknown r-----
[root@node2 ~]# drbdadm -- --discard-my-dataconnect mydata
切换至node1,设置其为主节点
[root@node1 ~]# drbdadm primary mydata
[root@node1 ~]# mount /dev/drbd0 /mydata
在Node1主节点上手动连接资源
[root@node1 ~]#drbdadm connect mydata
最后查看各个节点状态,连接已恢复正常
[root@node1 ~]# cat /proc/drbd
version: 8.4.3 (api:1/proto:86-101)
GIT-hash: 89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@,2013-05-27 04:30:21
0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/InconsistentC r-----
ns:28700 nr:0 dw:48 dr:30145 al:2 bm:5 lo:0 pe:1 ua:0 ap:0ep:1 wo:f oos:1024
[===================>] sync'ed:100.0% (1024/28700)K
finish: 0:00:00 speed: 6,916 (6,916) K/sec
查看drbd当前状态
[root@node1 ~]# drbd-overview
0:mydata/0 Connected Primary/Secondary UpToDate/UpToDate C r-----/mydata ext4 2.0G 97M 1.8G 6%
同步完成,最后将双方drbd服务关闭启动corosync即可
[root@node1 ~]# /etc/init.d/drbd stop
[root@node1 ~]# /etc/init.d/corosync start