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

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各个参数要熟悉,特别是性能调优参数,具体看官方文档。

猜你喜欢

转载自yq.aliyun.com/articles/677609
今日推荐