欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

drbd(二):配置和使用

程序员文章站 2022-03-13 11:13:00
本文目录:1.drbd配置文件2.创建metadata区并计算metadata区的大小3.启动drbd4.实现drbd主从同步5.数据同步和主从角色切换6.drbd脑裂后的解决办法7.drbd多卷组配置 drbd的简介、同步机制和安装见另一篇文章:drbd(一):简介、同步机制和安装。 本文所述为d ......

本文目录:
1.drbd配置文件
2.创建metadata区并计算metadata区的大小
3.启动drbd
4.实现drbd主从同步
5.数据同步和主从角色切换
6.drbd脑裂后的解决办法
7.drbd多卷组配置

drbd的简介、同步机制和安装见另一篇文章:drbd(一):简介、同步机制和安装

本文所述为drbd8.4的配置,和8.4版本之前的版本,以及drbd9版本的差别都非常大。

1.drbd配置文件

drbd的主配置文件/etc/drbd.conf,为了管理的便捷性,在此文件中使用了include指令指定了包含的配置文件段,默认的是在/etc/drbd.d/目录下。在此目录有全局配置文件global_common.conf和其他配置文件*.res文件。其中在主配置文件中include全局配置文件的指令只能出现一个,且必须出现在最前面。

两个节点的配置文件应尽量完全一致。

/usr/share/doc/drbd-版本/下有drbd.conf的样例配置文件。

以下是global_common.conf的结构。

global {
usage-count yes;  # 是否参加drbd的使用者统计,默认此选项为YES
}

common {      # common段定义每一个资源从此继承的参数,非必须,但建议将多个资源共享的参数定义在此以降低配置文件的复杂度
        handlers {
}
        startup {
        }
        options {
        }
        disk {
}
        net {
        }
}

全局配置修改如下:

global {
        usage-count no;
}

common {
handlers{       # 定义出现以下问题(如splitbrain或out-of-sync错误)时处理策略
          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";
          split-brain "/usr/lib/drbd/notify-split-brain.sh root";
          out-of-sync "/usr/lib/drbd/notify-out-of-sync.sh root";
}
        disk {
              on-io-error detach; # 当发生io错误时,直接拔除备节点设备
              resync-rate 600M;
        }
       # syncer {       # 注意,8.4版本已不支持该选项,要配置相关项,参见https://docs.linbit.com/docs/users-guide-8.4/#s-recent-changes-config
       #    rate 10M;   # re-sync速率,官方建议设置为网络IO和磁盘IO能力最小者的30%
       #    verify-alg crc32c;  # 用于校验block是否一致
        }
        protocol C; # 定义使用C协议,即同步复制。可不定义,此为默认
}

再新建一个配置文件data1.res,里面定义资源。

resource data1 {   # 定义资源名称
  on drbd1.longshuai.com {   # 指定在drbd1.longshuai.com节点上,节点名要和uname -n一致 
    device    /dev/drbd0;    # 指定drbd设备,0是其此设备号
    disk      /dev/sdb5;     # 指定要同步的数据分区
    address   192.168.100.51:7788; # 指定监听用来同步数据的地址和端口,此处指定为数据同步专用地址eth1
    meta-disk /dev/sdb1;  
}
  on drbd2.longshuai.com {
    device    /dev/drbd0;
    disk      /dev/sdb5;
    address   192.168.100.52:7788;
    meta-disk /dev/sdb1;
  }
}

或者简化为如下:

resource data1 {
    device    /dev/drbd0;
    disk      /dev/sdb5;
    meta-disk /dev/sdb1[0];
    on drbd1.longshuai.com {
        address   192.168.100.51:7788;
    }
    on drbd2.longshuai.com {
        address   192.168.100.52:7788;
    }
}

resource段用于定义drbd资源,每个资源通常定义在一个单独的位于/etc/drbd.d目录中的以.res结尾的文件中。资源在定义时必须为其命名,名字可以由非空白的ASCII字符组成。每一个资源段的定义中至少要包含两个节点,其它参数均可以从common段或drbd的默认中进行继承。

其中上述配置文件的meta-disk有三种记录方式:internal/device/device[index_num]。其中不管是哪种方式,metadata存放的分区不能格式化,哪怕使用internal时metadata和一般data在同一个分区也不能格式化该分区。

internal是将元数据也写入到数据分区的尾部,即数据和元数据同分区。如果指定的device没有给定index时,则表示元数据存储到该设备中。如果某节点指定device[index_num],那么指定几次元数据分区索引就必须大于128M的几倍,例如上述文件中drbd1.longshuai.com节点指定了/dev/sdb1[0],那么sdb1就必须大于128M,如果此时其他资源的节点也指定了同一台服务器的/dev/sdb1[1],则指定了两次就必须大于256M。指定为internal和device时,元数据区的大小是drbd自行计算的。

2.创建metadata块(初始化)并计算metadata区的大小

drbdadm create-md [all|resource_names]

两节点都初始化。

[root@drbd1 drbd.d]# drbdadm create-md data1
initializing activity log
NOT initializing bitmap
Writing meta data...
New drbd meta data block successfully created.

初始化成功后,可以使用下面几个命令来获取drbd的metadata区信息。

[root@drbd1 ~]# drbdadm show-gi data1

       +--<  Current data generation UUID  >-
       |               +--<  Bitmap's base data generation UUID  >-
       |               |                 +--<  younger history UUID  >-
       |               |                 |         +-<  older history  >-
       V               V                 V         V
0000000000000004:0000000000000000:0000000000000000:0000000000000000:0:0:0:0:0:0:0
                                                                    ^ ^ ^ ^ ^ ^ ^
                                      -<  Data consistency flag  >--+ | | | | | |
                             -<  Data was/is currently up-to-date  >--+ | | | | |
                                  -<  Node was/is currently primary  >--+ | | | |
                                  -<  Node was/is currently connected  >--+ | | |
         -<  Node was in the progress of setting all bits in the bitmap  >--+ | |
                        -<  The peer's disk was out-dated or inconsistent  >--+ |
      -<  This node was a crashed primary, and has not seen its peer since   >--+

flags: Secondary, StandAlone, Inconsistent
meta-data: clean
zero size device -- never seen peer yet?

从上面命令的结果中,可以看出数据的代数,还能获取一些节点状态信息。

关于drbd的代数,它在drbd的内部机制中,用于实现:
(1).判断两节点是否是同一个集群的节点。也就是说,对方节点是不是自己的对端节点。因为有可能出现意外连接,却不是自己对端的情况。
(2).判断节点设备是否需要全部重新同步(re-sync)或者部分重新同步。
(3).判断重新同步的方向。即是从节点1重新同步到节点2还是从节点2重新同步到节点1。
(3).标识节点是否处于脑裂(brain split)。

[root@drbd1 ~]# drbdadm dump-md data1
# DRBD meta data dump
# 2018-03-29 22:53:52 +0800 [1522335232]
# drbd1.longshuai.com> drbdmeta 0 v08 /dev/sdb1 flex-external dump-md
#

version "v08";

# md_size_sect 1951744
# md_offset 0
# al_offset 4096
# bm_offset 36864

uuid {
    0x0000000000000004; 0x0000000000000000; 0x0000000000000000; 0x0000000000000000;
    flags 0x00000000;
}
# al-extents 257;
la-size-sect 0;
bm-byte-per-bit 4096;
device-uuid 0x0A293D126547895D;
la-peer-max-bio-size 0;
al-stripes 1;
al-stripe-size-4k 8;
# bm-bytes 0;
bm {
}
# bits-set 0;

从此命令中可以获知不同标记代数的uuid值,以及metadata的元数据信息,例如md_size_sect=1951744表示元数据所在分区占用了1951744个扇区。注意,该命令不要在drbd设备已启动的情况下执行。

知道这两个命令可以获取一些信息后,现在我们要做的是计算metadata部分的数据大小。这个大小在"修改drbd设备空间大小"时有用。

首先获取元数据所在分区的扇区数。即上面结果中的"md_size_sect"。不过也可以使用块设备工具blockdev来获取。

[root@drbd1 ~]# blockdev --getsz /dev/sdb1
1951744

有了该值,根据计算公式:Size = (md_size_sect/2^18)*8*N+72进行计算。其中md_size_sect如上计算,N是对端的数量,一般情况下drbd实现的是双节点,因此N=1,可以不用考虑。计算的结果是扇区数。

因此,此处计算的结果为:1951744/1024/256*8+72=131.5625共132扇区。如果要转换为KB大小,则再除以2即可(假设扇区大小为512bytes)。

3.在节点上启动drbd

可使用如下命令来管理资源的启动、停止。

drbdadm {up|down} {all|resource_names}

例如:

drbdadm up data1

如果启动报以下错误,则可能是因为对metadata进行了格式化。解决方法是将其删除再重新创建但不要格式化。

0: Failure: (119) No valid meta-data signature found.

此时可以查看/proc/drbd文件来查看drbd中配置的资源的状态,也可以使用命令drbd-overview RESOURCEdrbdadm status RESOURCE来查看。如果角色ro是从/从,则表明配置成功,若有一端是unknown,则表明和对方不能通信,可能是主机路由的问题,这样会导致脑裂的问题。

cat /proc/drbd
version: 8.4.9-1 (api:1/proto:86-101)
GIT-hash: 9976da086367a2476503ef7f6b13d4567327a280 build by mockbuild@Build64R6, 2016-12-13 18:38:15
 0: 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:6297452

状态信息极其重要,其中:

  • cs:connection state,必须是connected状态才表示连接成功。
  • ro:roles,各节点是是primary还是secondary。
  • ds:disk state,数据的状态,由此判断是否要同步、重新同步、正在同步、同步完成、是否一致等等信息。

关于drbd的状态信息,见另一篇文章。

实际上,drbdadm up启动drbd设备时做了很多工作,如果细致划分的话,可以将"drbdadm up"拆分为以下几个动作:

  1. 将drbd的资源关联到底层设备(metadata和data区)上,使之能通过底层设备存、取数据。该过程调用的是drbdsetup程序。
    drbdadm attach data1
    
  2. 加载drbd资源的同步参数。
    drbdadm syncer data1
    
  3. 连接对端。
    drbdadm connect data1
    
    这些命令在drbdadm中部分已失效,放在这里只是为了说明"up"时所执行的几个步骤。

到目前为止,drbd的资源已经关联完成,也已经准备好进行同步,所不知道的仅仅只是谁作为同步的源端,谁做为同步的目标端,也就是primary和secondary的角色。

4.实现drbd的主从同步

在需要设置为主机点的机器上执行:

drbdadm primary --force data1  # 第一次初始化同步只能执行这个
# 或者
drbdsetup /dev/drbd0 primary

其中"--force"表示强制升级为primary,这会导致本节点的数据强制同步到对端上。

在drbd8.4之前,没有"--force"选项,而是使用等价的"--overwrite-data-of-peer",由于它调用的是drbdsetup,所以同时还要在选项前加上"--"表示drbdadm将此选项传递给drbdsetup,即:

drbdadm -- --overwrite-data-of-peer primary data1

由于是第一次执行同步,因此该过程会同步整个分区进行初始化。

[root@drbd1 ~]# 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
 0: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:812136 nr:0 dw:0 dr:813048 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:4069272
        [==>.................] sync'ed: 16.7% (3972/4764)M
        finish: 0:02:24 speed: 28,216 (17,652) K/sec

可以看到本端已经设置为主节点,且ds的一端是uptodate状态,最后还看到了镜像到对方的进度信息。

当镜像完成后,再查看资源的信息。可以发现两端的ds都变成uptodate状态了。说明镜像完成了。

[root@drbd1 ~]# 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
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:4881408 nr:0 dw:0 dr:4882320 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

5.数据同步和主从角色切换

现在已经有一端是主节点了。drbd的主从节点中,只有主节点是可以挂载并进行读写的。所以在主节点上挂载drbd设备(可能需要重新格式化data分区,而且如果metadata使用的是internal模式,则需要格式化分区才OK)。

挂载drbd到mnt,然后向其中拷贝一个文件。

[root@drbd1 ~]# mount /dev/drbd0 /mnt
[root@drbd1 ~]# cp /etc/inittab /mnt
[root@drbd1 ~]# ls /mnt
inittab  lost+found

如果对端也有这个文件则说明同步成功了,但是对端是从节点,无法读取数据,所以只能切换主从角色再查看。不过在,实验环境下直接把从节点的drbd给down掉,再直接挂载/dev/sdb5也是可以的。

首先将主节点切换为从节点,必须先卸载挂载点才行。

[root@drbd1 ~]# umount /mnt
[root@drbd1 ~]# drbdadm secondary data1 
[root@drbd1 ~]# drbd-overview
 0:data1/0  Connected Secondary/Secondary UpToDate/UpToDate

再在从节点上将自己设置为主节点,然后挂载drbd设备,再查看是否有文件同步过来了。

[root@drbd2 ~]# drbdadm primary data1
[root@drbd2 ~]# mount /dev/drbd0 /mnt
[root@drbd2 ~]# ls /mnt
inittab  lost+found

这说明实现了数据同步。但是这样手动切换来切换去的很麻烦,一般会将其交给heartbeat或者corosync来管理,实现drbd的自动切换。

6.drbd脑裂的解决方法

当DRBD的两节点都发现对方后,并都交换了初始化握手协议后,发现双方都是primary角色,就会出现脑裂。出现脑裂后,由于两端节点都可以挂载、写数据,会导致数据的混乱。

当检测到出现脑裂时,drbd会立即中断双方的连接,并在日志中记录

Split-Brain detected, dropping connection!

在出现脑裂的时候,一定有一端的连接状态处于StandAlone,另一端的状态可能是StandAlone(当双方同时检测到脑裂),也可能是Connecting(当一端先检测到脑裂立即中断连接后使得另一端无法再检测出脑裂)。

出现脑裂的时候,如果没有配置drbd自动从脑裂状态恢复,那么必须进行人为的手动干涉。干涉的方法是放弃一端的数据,这一端称为"脑裂的受害者",另一端保存数据的节点则称为"脑裂的幸存者"。

处理方法如下:

(1).在脑裂的受害者节点上执行:

drbdadm disconnect {resource | all}   # 先中断连接,防止再次写入数据
drbdadm secondary {resource | all}    # 设置为secondary
drbdadm connect --discard-my-data {resource | all}   # 丢弃数据,并再次连接

(2).如果脑裂的幸存者节点也是StandAlone状态,则执行下面的命令重新连接,如果仍然保持Connecting状态,则不需任何操作:

drbdadm disconnect {resource | all}
drbdadm connect    {resource | all}

当干涉完两边后,两边重新建立连接,重新握手交换初始化协议信息。此时,脑裂的受害者端的状态将变为SyncTarget,表示同步的目标端,它将从另一节点上获取数据。

但注意,受害者在SyncTarget状态下同步数据时,并不会从幸存者节点获取所有数据,而是按照自己节点上的事务信息进行回滚,再从幸存者节点上获取回滚后还缺少的数据因此,drbd脑裂后完成数据同步也是很快的。

7.drbd多卷组配置

前文实验中使用的配置文件如下:

[root@drbd2 ~]# drbdadm dump data1
# resource data1 on drbd2.longshuai.com: not ignored, not stacked
# defined at /etc/drbd.d/data1.res:1
resource data1 {
    on drbd1.longshuai.com {
        device           /dev/drbd0 minor 0;
        disk             /dev/sdb5;
        meta-disk        /dev/sdb1;
        address          ipv4 192.168.100.51:7788;
    }
    on drbd2.longshuai.com {
        device           /dev/drbd0 minor 0;
        disk             /dev/sdb5;
        meta-disk        /dev/sdb1;
        address          ipv4 192.168.100.52:7788;
    }
}

它等价于:

resource data1 {
        device /dev/drbd0;
        disk /dev/sdb5;
        meta-disk /dev/sdb1;
        on drbd1.longshuai.com {
                address 192.168.100.51:7788;
        }
        on drbd2.longshuai.com {
                address 192.168.100.52:7788;
        }
}

其实它还等价于:

resource data1 {
        volume 0 {
                device /dev/drbd0;
                disk /dev/sdb5;
                meta-disk /dev/sdb1;
        }
        on drbd1.longshuai.com {
                address 192.168.100.51:7788;
        }
        on drbd2.longshuai.com {
                address 192.168.100.52:7788;
        }
}

drbd会为没有分卷组的资源使用默认卷组"volume 0"。

如果需要多个底层设备(磁盘、分区、LVM、RAID等)提供drbd的同步功能,可以设置多个卷组。

例如,除了上面使用的/dev/sdb{5,1}外,添加/dev/sdc1(data区)、/dev/sdc2(metadata区)到另一个卷组。

resource data1 {
        volume 0 {
                device /dev/drbd0;
                disk /dev/sdb5;
                meta-disk /dev/sdb1;
        }
        volume 1 {
                device /dev/drbd1;
                disk /dev/sdc1;
                meta-disk /dev/sdc2;
        }
        on drbd1.longshuai.com {
                address 192.168.100.51:7788;
        }
        on drbd2.longshuai.com {
                address 192.168.100.52:7788;
        }
}

如果第二个卷组是在drbd已经运行后再添加的完全的新分区,则需要先创建元数据区、调整配置文件、启动资源等过程。

两边节点都执行:

drbdadm create-md data1/1  # data1/1表示data1资源下的卷组1
drbdadm adjust data1       # 调整资源,相当于reload资源配置文件

主节点执行:

drbdadm --force primary data1/1

查看两卷组的状态信息:

[root@drbd1 ~]# 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
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:76408 nr:0 dw:76408 dr:3441 al:22 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
 1: cs:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r-----
    ns:5352 nr:0 dw:0 dr:6264 al:8 bm:0 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:4876056
        [>....................] sync'ed:  0.2% (4760/4764)M
        finish: 0:43:32 speed: 1,784 (1,784) K/sec

再次提醒,两端的配置文件应当尽量保持一致,因此最好不要随意分区。

 

回到Linux系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7048359.html
回到网站架构系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7576137.html
回到数据库系列文章大纲:http://www.cnblogs.com/f-ck-need-u/p/7586194.html
转载请注明出处:http://www.cnblogs.com/f-ck-need-u/p/8678883.html

注:若您觉得这篇文章还不错请点击右下角推荐,您的支持能激发作者更大的写作热情,非常感谢!