DRBD(Distributed Relicated Block
DRBD(Distributed Relicated Block Device 分布式复制块设备), 可以解决磁盘单点故障。一般情况下只支持2个节点。
一、DRBD的工作模式
1、主从模型master/slave(primary/secondary)
这种机制,在某一时刻只允许有一个主节点,主节点的作用是可以挂载使用,写入数据等;从节点作为主节点的镜像,是主节点的备份。
这样的工作机制的好处是可以有效的避免磁盘出现单点故障,文件系统不会出现错乱。
2、双主模型dula primary(primary/primary)
所谓双主模型是2个节点都可以当做主节点来挂载使用。那么思考一个问题?当第一个主节点对某一文件正在执行写操作,此时另一个节点也正在对同一文件也要执行操作,结果会如何?
一般这种情况会造成文件系统的错乱,导致数据不能正常使用。原因是:对文件的加速机制是由操作系统内核所管理的,一个节点对文件加速后,另一个节点并不知道对方的锁信息。
解决办法是:使用集群文件系统。集群文件系统使用分布式文件锁管理器,当一个节点对文件加锁之后会通过某种机制来通知其他节点锁信息,从而实现文件锁共享。
drbd8.4的官方文档.png
二、DRBD的复制模型
大致的工作原理如下图:
image.png
当某一进程对某一文件执行了写操作时,写操作在上图执行到那个过程时就认为文件已经同步完成。
复制协议:
A协议:异步复制(asynchronous)如上图 文件写操作执行到A点是就认为写入磁盘成功。性能好,数据可靠性差。
B协议:半同步复制(semi sync)如上图 文件写操作执行到B点是就认为写入磁盘成功。性能好,数据可靠性介于A和C之间。
C协议:同步复制( sync)如上图 文件写操作执行到C点是就认为写入磁盘成功。性能差,数据可靠性高。也是drbd默认使用的复制协议
三、drbd的配置(主从模式)
环境需求:
CentOS7
虚拟机1的ip:192.168.129.157 node1
虚拟机2的ip:192.168.129.158 node2
准备工作:
在node1和node2上执行:设置主机名和主机名解析文件,因为drbd 2个节点之间通信是基于主机名的
vi /etc/hosts
192.168.129.157 node1
192.168.129.158 node2
hostnamectl set-hostname node1
reboot
在node1和node2执行:免密码ssh互信
ssh-keygen
ssh-copy-id -i /root/.ssh/id_rsa.pub node1
安装DRBD
DRBD分为两部分,一部分是工作内核中的模块部分,一部分是工件在用户空间的管理工具,2.6.33以后的内核中已经集成了DRBD的模块,只安装管理工具即可,旧内核需要为内核打补丁才可以,有爱好者把补丁做成了rpm包名字为kmod-drbd,安装它即可,补丁包一定与内核版本一致
在node1和node2上执行:
rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-2.el7.elrepo.noarch.rpm
yum install -y kmod-drbd84 drbd84-utils kernel*
在node1上执行:
- 编辑全局配置文件
vi /etc/drbd.d/global_common.conf
global {
usage-count no; #是否参加DRBD官方统计
}
common { #common各个资源共用的选项
protocol C; #使用DRBD的同步协议,添加这一行
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";
#需要把这三行的注释去掉
}
disk {
on-io-error detach; #发生i/o错误的处理方法,detach将镜像磁盘直接拔除
}
syncer {
rate 1024M; #设置主备节点同步时的网络速率,添加这个选项
}
}
注释: on-io-error 策略可能为以下选项之一
detach 分离:这是默认和推荐的选项,如果在节点上发生底层的硬盘I/O错误,它会将设备运行在Diskless无盘模式下
pass_on:DRBD会将I/O错误报告到上层,在主节点上,它会将其报告给挂载的文件系统,但是在此节点上就往往忽略(因此此节点上没有可以报告的上层)
-local-in-error:调用本地磁盘I/O处理程序定义的命令;这需要有相应的local-io-error调用的资源处理程序处理错误的命令;这就给管理员有足够自由的权力命令命令或是脚本调用local-io-error处理I/O错误
- 定义一个mysql资源
vi /etc/drbd.d/mysql.res
resource mysql { #资源名称
protocol C; #使用协议
meta-disk internal;元数据
device /dev/drbd1; #DRBD设备名称
syncer {
verify-alg sha1;# 加密算法
}
net {
allow-two-primaries;
}
on node1 { #hostname一定要设为node1,不然会报错的
disk /dev/sdb; # drbd1映射的的磁盘
address 192.168.129.157:7789; #drbd监听7789端口
}
on node2 {
disk /dev/sdb;
address 192.168.129.158:7789;
}
}
以上文件在两个节点上必须相同,因此,可以基于ssh将刚才配置的文件全部同步至另外一个节点。
在node1上执行:
把配置文件copy到对面的机器上,从node1传到node2:
scp -rp /etc/drbd.d/* node2:/etc/drbd.d/
在node1和node2执行:
创建设备元数据。这一步必须仅在创建初始化设备时完成。它初始化DRBD元数据。
drbdadm create-md mysql
启动,mysql资源
drbdadm up mysql
第一次启动drbd时,两个dabd节点默认都处于Secondary状态。
cat /proc/drbd
设置node1为主节点并挂载
在node1上执行,设置主节点:
drbdadm primary mysql
安装成功的结果:
[root@node1 data]# drbd-overview1:mysql/0 Connected **Primary/Secondary UpToDate/UpToDate** /mnt/data xfs 5.0G 33M 5.0G 1%
[root@node2 ~]# drbd-overview
1:mysql/0 Connected **Secondary/Primary UpToDate/UpToDate**
在node1上执行,挂载:
mkdir /mnt/data
mkfs.xfs /dev/drbd1
mount /dev/drbd1 /mnt/data
假如在node2上的操作,则出现以下结果:
[root@node2 ~]#mkfs.xfs /dev/drbd1
mkfs.xfs: cannot open /dev/drbd1: 只读文件系统
注:Secondary节点上不允许对DRBD进行任何操作,所有的读写操作只能在Primary节点上进行,只有当Primary节点挂掉时,Secondary节点才能提升为Primary节点继续工作
主从切换
主从手动切换
若备节点需挂载磁盘,则卸载主节点的磁盘
在node1的操作,卸载:umount /mnt/data
drbdadm secondary mysql
在node2的操作,设置为主节点,不用再格式化,挂载:drbdadm primary mysql
mkdir /mnt/data
mount /dev/drbd1 /mnt/data
模拟主节点node1挂掉(关闭主机node1)
node1挂掉时,此时挂载的DRBD分区就自动在主用节点卸载了,因为DRBD设备,只有到DRBD服务启动的时候才能加载到系统中
[root@node2 ~]# drbd-overview1:mysql/0 WFConnection Secondary/Unknown UpToDate/DUnknown
手动把node2改为主节点:
drbdadm primary mysql
mount /dev/drbd1 /mnt/data[root@node2 ~]# drbd-overview
1:mysql/0 WFConnection **Primary/Unknown** UpToDate/DUnknown /mnt xfs 5.0G 33M 5.0G 1%
*查看node2,数据有没有和之前的主节点node1同步,结果成功备份了主节点创建的node1.txt:
[root@node2 ~]# cat /mnt/data/node1.txt
node1
[root@node2 ~]# cat > /mnt/data/node2.txt
node2
恢复主节点(重新开机)
[root@node1 ~]# drbdadm up mysql
[root@node1 ~]# drbd-overview1:mysql/0 WFConnection **Secondary/Unknown** UpToDate/DUnknown
再次查看
[root@node2 ~]# drbd-overview1:mysql/0 Connected Secondary/Primary UpToDate/UpToDate
手动切换主从,在node1发现了在node2创建的node2.txt文件
问题
- 需要更新内核,并重启主机
问题现象:
[root@node2 ~]# drbdadm create-md mysqlmodinfo: ERROR: Module drbd not found. drbd.d/global_common.conf:68: Parse error: 'a syncer option keyword' expected, but got 'rate'
更新内核:
[root@node1]# lsmod | grep drbd
[root@node1]#yum install gcc gcc-c++ make glibc flex kernel kernel-devel kernel-headers
[root@node1]#reboot
脑裂产生的原因:人为配置错误,其他
脑裂产生后果:DRBD两边的磁盘数据不一致,并且不知道自动恢复。
- 发生脑裂现象
问题现象:
[root@node1 ~]# cat /proc/drbd1: cs:StandAlone ro:Primary/Unknown ds:UpToDate/DUnknown r----s
[root@node2 ~]# cat /proc/drbd
1: cs:StandAlone ro:Primary/Unknown ds:UpToDate/DUnknown r----s
解决方法:
- Primary节点
1.Primary节点查看连接状态为 StandAlone ,手动连接mysql资源
[root@master1 ~]# drbdadm connect mysql- Secondary节点
- 断开连接
[root@master2 ~]# drbdadm disconnect mysql- 设置为secondary状态
[root@master2 ~]# drbdadm secondary mysql- 告诉slave,secondary 上的数据不正确,以primary 上的数据为准
[root@master2 ~]# drbdadm -- --discard-my-data connect mysql