一、drbd基础

1.drbd基础概念

    drbd(全称为Distributed Replicated Block Device,简称drbd)分布式块设备复制,说白了就是在不同节点上两个相同大小的设备块级别之间的数据同步镜像。drbd是由内核模块和相关脚本而构成,用以构建高可用性的集群。在高可用(HA)解决方案中使用drbd的功能,可以代替使用一个共享盘阵存储设备。因为数据同时存在于本地主机和远程主机上,在遇到需要切换的时候,远程主机只需要使用它上面的那份备份数据,就可以继续提供服务了。

2.drbd工作原理

wKioL1X-rwOCUvaAAAHy9Qgd4vg151.jpg

    从上图我们可以清晰的看出drbd是以主从(Primary/Secondary)方式工作的,这点原理与mysql的主从复制的架构有些相似。主 节点上的drbd提升为Primary并负责接收写入数据,当数据到达drbd模块时,一份继续往下走写入到本地磁盘实现数据的持久化,同时并将接收到的 要写入的数据发送一分到本地的drbd设备上通过tcp传到另外一台主机的drbd设备上(Secondary node),另一台主机上的对应的drbd设备再将接收到的数据存入到自己的磁盘当中。这里与mysql的基于通过二进制日志完成数据的复制的确很相似, 但是也有一些不同之处。比如:mysql的从节点不能写但是可以读,但是drbd的从节点是不能读、不能挂载。

   因此,drbd对同一设备块每次只允许对主节点进行读、写操作,从节点不能写也不能读。这样感觉是不是对主机有资源浪费,的确HA架构中为了提供冗余能 力是有资源浪费,但是你可以对上图的两台主机建立两个drbd资源并互为主从,这样两台机器都能利用起来,但是配置起来就复杂了。但是话又说回来,用 drbd作为廉价的共享存储设备,要节约很多成本,因为价格要比专用的存储网络便宜很多,其性能与稳定性方面也还不错。

3.drbd复制模式(协议)

     A协议:异步复制协议。一旦本地磁盘写入已经完成,数据包已在发送队列中,则写被认为是完成的。在一个节点发生故障时,可能发生数据丢失,因为被写入到远程节点 上的数据可能仍在发送队列。尽管,在故障转移节点上的数据是一致的,但没有及时更新。因此,这种模式效率最高,但是数据不安全,存在数据丢失。

   B协议:内存同步(半同步)复制协议。一旦本地磁盘写入已完成且复制数据包达到了对等节点则认为写在主节点上被认为是完成的。数据丢失可能发生在参加的两个节点同时故障的情况下,因为在传输中的数据可能不会被提交到磁盘

   C协议:同步复制协议。只有在本地和远程节点的磁盘已经确认了写操作完成,写才被认为完成。没有数据丢失,所以这是一个群集节点的流行模式,但I/O吞吐量依赖于网络带宽。因此,这种模式数据相对安全,但是效率比较低。

4.drbd资源:用来定义一组drbd设备,它包含以下四个属性。

    资源名称:可以是除了空白字符外的任意ACSII码字符;
    DRBD设备:在双方节点上,此DRBD设备的设备文件,一般为/dev/drbdN,其主设备号147;
    磁盘:在双方节点上,各自提供的存储设备;
    网络配置:双方数据同步时所使用的网络属性;

二、drbd安装与配置

1.环境

    node1(CentOS6.5):192.168.220.132

    node2(CentOS6.5):192.168.220.133

2.准备工作

     配置各节点SSH互信:

# node1
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.220.133
# node2
ssh-keygen -t rsa -f ~/.ssh/id_rsa -P ''
ssh-copy-id -i .ssh/id_rsa.pub root@192.168.220.132

    配置主机名称与uname -n一致,并通过/etc/hosts解析:

# node1
hostname node1.wyb.com
 sed -i 's@\(HOSTNAME=\).*@\1node1.wyb.com@g' /etc/sysconfig/network
echo '192.168.220.132 node1.wyb.com   node1' >> /etc/hosts
echo '192.168.220.133 node2.wyb.com   node2' >> /etc/hosts
# node2
hostname node2.wyb.com
 sed -i 's@\(HOSTNAME=\).*@\1node2.wyb.com@g' /etc/sysconfig/network
echo '192.168.220.132 node1.wyb.com   node1' >> /etc/hosts
echo '192.168.220.133 node2.wyb.com   node2' >> /etc/hosts

    时间同步:

# node1 node2
ntpdate asia.pool.ntp.org
echo '*/3 * * * * /usr/sbin/ntpdate asia.pool.ntp.org &> /dev/null' >> /var/spool/cron/root

    分别在两个节点上准备一个大小相同的磁盘设备(具体操作省略)。

3.安装

    drbd共有两部分组成:内核模块和用户空间的管理工具。其中drbd内核模块代码已经整合进Linux内核2.6.33以后的版本中,因此,如果您的内核版本高于此版本的话,你只需要安装管理工具即可;否则,您需要同时安装内核模块和管理工具两个软件包,并且此两者的版本号一定要保持对应。由于CentOS6.5自带yum源没有drbd软件包,所以需要手动下载对应版本软件包安装,下载地址为:http://rpm.pbone.com。

#node1 node2
[root@node1 drbd]# ls
drbd-8.4.3-33.el6.x86_64.rpm  drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm
[root@node1 drbd]# yum --nogpgcheck localinstall *.rpm -y

4.配置

    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的默认中进行继承而无须定义。

    配置主配置文件:

[root@node1 drbd.d]# vim /etc/drbd.d/global_common.conf 
global {
        usage-count no;
        # minor-count dialog-refresh disable-ip-verification
}

common {
        protocol C;    #定义drbd复制协议
        handlers {    #定义处理机制程序
                # These are EXAMPLE handlers only.
                # They may have severe implications,
                # like hard resetting the node under certain circumstances.
                # Be careful when chosing your poison.

                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 degr-wfc-timeout outdated-wfc-timeout wait-after-sb
        }

        options {
                # cpu-mask on-no-data-accessible
        }

        disk {
                on-io-error detach;
                # size max-bio-bvecs on-io-error fencing disk-barrier disk-flushes
                # disk-drain md-flushes resync-rate resync-after al-extents
                # c-plan-ahead c-delay-target c-fill-target c-max-rate
                # c-min-rate disk-timeout
        }

        net {
                cram-hmac-alg "sha1";    #设置加密算法 
                shared-secret "mydrbd784uif";    #设置加密密钥 
                # protocol timeout max-epoch-size max-buffers unplug-watermark
                # connect-int ping-int sndbuf-size rcvbuf-size ko-count
                # allow-two-primaries cram-hmac-alg shared-secret after-sb-0pri
                # after-sb-1pri after-sb-2pri always-asbp rr-conflict
                # ping-timeout data-integrity-alg tcp-cork on-congestion
                # congestion-fill congestion-extents csums-alg verify-alg
                # use-rle
        }
        syncer {
                rate 200M;    #定义drbd复制时最大使用带宽
        }
}

    资源定义:

[root@node1 drbd.d]# vim mydrbd.res
resource mydrbd {    #资源名称
  on node1.wyb.com {    #定义主机名为node2.wyb.com的节点的属性配置
    device    /dev/drbd0;    #drbd设备名称
    disk      /dev/sda6;    #drbd使用的物理设备
    address   192.168.220.132:7789;    #监听套接字
    meta-disk internal;    #drbd元数据存放位置
  }
  on node2.wyb.com {
    device    /dev/drbd0;
    disk      /dev/sda6;
    address   192.168.220.133:7789;
    meta-disk internal;
  }
}

注:相同属性可以定义在resource外部。

    将刚才配置的文件全部同步至另外一个节点:

scp -r /etc/drbd.*  node2:/etc

4、在两个节点上初始化已定义的资源并启动服务:
1)、初始化资源,在Node1和Node2上分别执行:

[root@node1 ~]# drbdadm create-md mydrbd
Writing meta data...
initializing activity log
NOT initializing bitmap    #错误可以忽略
lk_bdev_save(/var/lib/drbd/drbd-minor-0.lkbd) failed: No such file or directory
New drbd meta data block successfully created.
lk_bdev_save(/var/lib/drbd/drbd-minor-0.lkbd) failed: No such file or directory

2)、启动服务,在Node1和Node2上分别执行:

/etc/init.d/drbd start

3)、查看启动状态:

[root@node1 ~]# cat /proc/drbd 
version: 8.4.3 (api:1/proto:86-101)
GIT-hash: 89a294209144b68adb3ee85a73221f964d3ee515 build by gardner@, 2013-11-29 12:28:00
 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent 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:1055424

    也可以使用drbd-overview命令来查看:

[root@node1 ~]# drbd-overview 
  0:mydrbd/0  Connected Secondary/Secondary Inconsistent/Inconsistent C r-----

4)、设置node1为主节点:

drbdadm -- --overwrite-data-of-peer primary mydrbd

5)、创建文件系统
    文件系统的挂载只能在Primary节点进行,因此,也只有在设置了主节点后才能对drbd设备进行格式化:

[root@node1 ~]# mkfs -t ext4 /dev/drbd0
[root@node1 ~]# mkdir /mnt/drbd
[root@node1 ~]# mount /dev/drbd0 /mnt/drbd/

6)、切换Primary和Secondary节点
    对Primary/Secondary模型的drbd服务来讲,在某个时刻只能有一个节点为Primary,因此,要切换两个节点的角色,只能在先将原有的Primary节点设置为Secondary后,才能原来的Secondary节点设置为Primary:

#node1:
[root@node1 ~]# cp /etc/inittab /mnt/drbd/
[root@node1 ~]# umount /mnt/drbd/
[root@node1 ~]# drbdadm secondary mydrbd

#node2:
[root@node2 ~]# drbdadm primary mydrbd
[root@node2 ~]# drbd-overview 
  0:mydrbd/0  Connected Primary/Secondary UpToDate/UpToDate C r----- 
[root@node2 ~]# mkdir /mnt/drbd
[root@node2 ~]# mount /dev/drbd0 /mnt/drbd/
[root@node2 ~]# ls /mnt/drbd/
inittab  lost+found

成功!

参考资料:

drbd介绍、工作原理及脑裂故障处理:http://bruce007.blog.51cto.com/7748327/1330959

drbd安装配置、工作原理及故障恢复:http://www.linuxidc.com/Linux/2013-09/90321.htm