2.6.33 Linux 内核引入了一个有用的新服务,称为Distributed Replicated Block Device(DRBD)。该服务在运行期间可以将整块设备镜像到另一个网络主机上,允许进行数据块高可用性集群的开发。在 Linux 内核中探究 DRBD 背后蕴含的思想及其实现
高可用性简介
高可用性是提高可用性的一个系统设计原理。可用性,或者系统操作连续性的度量通常被定义为是一年中计算机正常运行时间的百分比,例如某一系统是 99% 可用的,那么一年中它的停机时间是 3.65 天。99% 通常被称为两个 9。与之相比,5 个 9(99.999%)最大停机时间降到每年 5.26 分钟。这差别很大,需要精心设计和高质量才能实现。
HA 最常见的实现是故障冗余。在这个模型中,您可以为一个给定资源定义多条路径,正常情况下使用可用路径,故障发生时使用冗余路径。企业级磁盘驱动器阐述了这一概念,因为它们提供两个访问端口(相比用户级驱动器的一个访问端口而言)。
存储冗余
在存储系统中使用冗余是不足为奇的,特别是在企业级设计中。标准方法 — RAID — 使用各种基础算法是很常见的,每一种算法都有不同的功能和特性。
RAID 是 1987 年在加利福尼亚大学伯克利分校第一次定义的。传统 RAID 级别包括 RAID-0 和 RAID-1,RAID-0 可以实现跨磁盘条带化(但是没有冗余),RAID-1 可以跨越两个磁盘实现镜像 ,这样一个信息就存在两个副本。对于 RAID-1,一个磁盘发生故障时,信息仍然可以通过其他副本获取。其他 RAID 级别包括 RAID-5 和 RAID-6,RAID-5 跨磁盘包含分布式奇偶校验码的块级条带化,RAID-6 包含带有双重分布式奇偶校验的块级条带化。尽管 RAID-5 支持一个驱动器故障,而 RAID-6 可以支持两个驱动器故障(尽管奇偶校验信息消耗更多的容量)。RAID-1 很简单,但是就容量利用而言太浪费。关于存储容量方面 RAID-5 和 RAID-6 更节省,但是它们通常需要额外硬件处理来避免奇偶校验计算加重处理器负荷。通常需要权衡利弊。图 1 提供了 RAID-0 和 RAID-1 模式的一个概览图。
图 1. Linux 中 RAID-0 和 RAID-1 模式的概览图
RAID 技术在继续发展,一些所谓的非标准技术蓄势待发。这些技术包括 Oracle 的 RAID-Z 模式(它解决了RAID-5 的 write-hold 问题);NetApp 的 RAID-DP(对角线奇偶校验) ,它扩展了 RAID-6;以及 IBM 的 RAID 1E(增强版本),它在奇数量的磁盘上可实现条带化(RAID-0)和镜像(RAID-1)。
DRBD 操作
现在,在深入钻研架构之前,让我们先看一下 DRBD 的操作。图 2 是在两个提供独立存储资源的独立服务器的背景之下的 DRBD 的一个概览。其中一个服务器被定义为主服务器,另一个是辅助服务器(通常是集群解决方案的一部分)。用户访问 DRBD 块设备,将其作为一个传统本地块设备,或一个存储区域网或网络附加存储解决方案。DRBD 软件为用户读写操作提供主服务器和辅助服务器之间的同步操作,以及其他同步操。
图 2. 基本 DRBD 操作模型
在主动/被动模式下,主节点用于所有用户的读写操作。如果集群解决方案检测到主节点故障,辅助节点升为主节点。写操作从主节点开始进行,同时执行本地存储和辅助存储(见图 3)。DRBD 支持两个模式的写操作,即完全同步和完全异步。
在完全同步模式下,在写事务被认可之前两个节点存储中的写操作必须是安全的 。在异步模式下,写数据被存储到本地节点存储中之后,写事务被认可;对等节点中的数据的副本出现在后台中。异步模式相对来说不×××全,因为在复制数据之前,有一个窗口显示可能发生的故障,但是它比完全同步模式更快,后者是数据保护最安全的模式。尽管推荐使用完全同步模式,但在出现远距离复制的情况下(比如在广域网中进行地理灾难恢复的场景),异步模式也是很有用的。读操作是使用本地存储执行的(除非本地磁盘发生故障,那时通过辅助节点访问辅助存储)。
Figure 3. 使用 DRBD 进行读/写操作
DRBD 也支持主动/被动模式,比如读和写操作可以在两个服务器上同时进行,这就是所谓的共享磁盘模式。该模式依赖一个共享磁盘文件系统,比如,Global File System (GFS) 或 Oracle Cluster File System 第 2 版(OCFS2),包含分布式锁管理功能。
DRBD 架构
DRBD 被分成独立的两部分:一个实现 DRBD 行为的内核模块和一组用于管理 DRBD 磁盘的用户空间管理应用程序(见图 4 )。内核模块实现一个用于虚拟块设备(跨网络在本地磁盘与远程磁盘之间复制)的驱动程序。作为一个虚拟磁盘,DRBD 提供一个供各种应用程序使用的灵活模型(从文件系统到依赖于一个原始磁盘的其他应用程序,比如数据库)。DRBD 模块不仅仅实现一个基础块驱动程序接口(磁盘配置细节在 drbd.conf 中有定义),而且也实现网络堆接口(其端点通过一个 IP 地址和端口号定义,也在 drbd.conf 中)。
图 4. Linux 架构中的 DRBD
在用户空间,DRBD 提供一组用于管理复制磁盘的实用工具。您可以使用drbdsetup
在 Linux 内核中配置 DRBD 模快,使用drbdmeta
管理 DRBD 元数据结构。一个同时使用这两个工具的包装实用工具是drbdadm
。高级管理工具是最常用的一个(从 /etc/drbd.conf 中的 DRBD 配置文件获取具体细节)。作为之前讨论的实用工具的一个前端,drbdadm
是管理 DRBD 最常用的。
您可以像使用其他任何磁盘那样使用 DRBD 提供的虚拟磁盘,其后的复制操作是透明的。现在,我们来看一下 DRBD 的一些主要功能,包括自我修复功能。
DRBD 主要功能
尽管复制磁盘的思想从概念上来说是很简单的(开发也相对比较容易),但是一个健壮的实现也有很多固有的复杂性。例如,向一个网络驱动器复制块相对比较简单,但是,处理故障和暂时断电(以及随后的驱动器同步)才是真正解决方案的开始。本节将介绍 DRBD 提供的主要功能,包括各种 DRBD 支持的故障模型。
复制模式
本文前面探究了节点之间复制数据的各种方法(尤其是这两种 — 完全同步和完全异步)。DRBD 支持每种方法的变体,这些方法比异步模式提供更多的数据保护,代价是性能略有下降。内存异步模式(或半异步模式)是介于同步模式和异步模式之间的一个变体。在这种模式下,写操作是在数据存储到本地磁盘并镜像到对等节点内存后被确认的。该模式提供更多保护,因为数据被镜像到另一个节点,这仅仅是针对易失性内存,而不是非易失性磁盘。这仍然可能丢失数据(例如,如果两个节点都发生故障),但是主节点故障不会引起数据丢失,因为数据已经被复制了。
联机设备验证
DRBD 允许对本地和远程对等设备进行联网验证(在输入/输出发生的同时)。验证意味着 DRBD 可以核实本地和远程磁盘是否是相互间的副本,这是一个耗时的操作。但是相比在节点之间移动数据进行验证,DRBD 提供了一个更为高效的方法。为了保护节点间的带宽(可能是一个受限资源),DRBD 不需要在节点间移动数据进行验证,而是移动数据(hash)的加密摘要。这样一来,一个节点可以计算一个块的散列值;将较小的签名转移到对等节点,该节点也可以计算散列值,然后对两者进行比较。如果散列值是相同的,数据块已经被正确的复制了。如果散列值不相同,将过期的数据块标记为不同步,随后的同步确保数据块是正确同步的。
通信完整性
节点之间的通信可能会将错误引入复制数据(由于软件或防火墙漏洞,或者不能被 TCP/IP 的校验码检测出来的其他错误)。为了提供数据的完整性,DRBD 计算消息完整性代码,以随数据一起在节点之间移动。这支持接收节点验证输入数据,并在发现一个错误时请求重发数据。DRBD 使用 Linux 加密应用程序编程接口,因此在完整性算法使用方面是比较灵活的。
自动恢复
DRBD 可以从多种错误中恢复,但是一个最严重的错误就是所谓的 “裂脑(split-brain)”。在这个错误场景中,节点之间的通信链发生故障,每个节点都认为自己是主节点。而对于主节点而言,每个节点支持写操作,而不会将这些操作传播到对等节点。这导致每个节点中的存储不一致。
大多数情况下,脑裂恢复是人工进行的,但是 DRBD 提供几个主动恢复这一状况的操作方法,所用恢复算法具体取决于实际的存储方式。
发生裂脑之后,同步存储最简单的方法是在链接出现故障时其中一个节点没有发现改变。这样,已经发生改变的节点与潜在对等节点进行简单的同步。另一个方法是丢弃变更较少的那个节点中的更改。这使得最大变更集合的节点可以继续工作,但也意味着一个主机上的变更将丢失。
还有两个方法是根据节点当时的状态丢弃更改。一种方法是将最后一次转换成主节点的那个节点中的变更丢弃,而另一种是将最老的主节点(是第一次转换成主节点的节点)中的变更丢弃。您可以在 DRBD 配置文件中操作每个节点,但是它们最终的使用取决于使用存储的应用程序以及数据是否有必要丢弃或进行人工恢复。
优化同步
复制存储设备的一个关键因素是节点之间数据同步的方法是否高效。DRBD 使用的模式其中两个是活动日志和快速同步位图。活动日志存储最近写入的块并确定故障恢复后应同步哪些块。快速同步位图确定连接断开时同步(或不同步)的数据块。节点重新连接之后,可使用这些位图快速同步节点,彼此之间进行精确的复制。时间是很重要的,因为它代表辅助磁盘不一致时的窗口。
linux disk scheduler:
在linux有4种调度算法
CFQ(Completely Fair Queuing 完全公平的排队〉(elevator=cfq):
这是默认算法,对于通用服务器来说通常是最好的选择。它试图均勻地分布对I/O带宽的访H在多媒休应用,总能保证audio、video及吋从磁盘读取 数据.但对于其他各类应用表现也很好。每个进程一个queue,每个queue按 照上述规则进行merge和sort。进程之间round robin调度,每次执行一个进程的4个淸求。可以调queued和quantum来优化
Deadline(elevator=deadline):
这个算法试图把每次请求的延迟降至最低。该算法重排了请求的顺序来提 高性能。可以调队列的过期的读写过程,如read_expire和write_expire 二个 参数来控制多久内一定要读到数据,超时就放弃排序。比较合适小文件。还可 以使用打开frontjierges来进行合并邻近文件。
NOOP(elevator=noop):
I/O请求被分配到队列,调度由硬件进行,只有当CPU时钟频率比较有限 时进行。
Noop对于I/O不那么操心,对所有的I/O请求都用FIFO队列形式处理,
默认认为I/O不会存在性能问题。这也使得CPU也不用那么操心。当然对于复杂一点的应用类型使用这个调度器,用户自己就会非常操心。
Noop调度算法指的是当诸求被存储到队列并交由I/O子系统处理时由磁盘硬件对其进行优化。该算法一般只对一些特定的硬件(例如RAMdisk和TCQ
disk等)。现代磁盘控制器都具备通过tagged command queuing进行优化的功 能。Tagged command queuing(TCQ)可以通过由磁盘控制器对I/O请求进行重新排序来减少磁头的动作。通常需要进行重组的I/O请求都会带有一个标识符,这样控制器在接收到这些I/O请求的时候会按照规则进行处理。有些应用程序需要对队列长度进行限制,而现代的设备驱动都具备用于控制队列长度的TCQ功能,并且该功能可以作为内核参数在系统启动的时候添加。 例如要控制SCSI驱动器Lun2的队列长度为64个请求,可以修改 /etc/grub, conf 并增加下而的内核参数:aic7xxx=tag_info:{{0, 0’ 64, 0’ 0’ 0’ 0}}
Anticipatory(elevator=as):
对读操作优化服务时间,在提供一个I/O的时候进行短时间等待,使进程 能够提交到另外的 I/O。Anticipatory scheduler (as)曾经一度是 Linux 2.6 Kernel的I/O scheduler。Anticipatory的屮文含义是〃预料的,预想的",这 个词的确揭示了这个算法的特点,简单的说有个I/O发生的时候,如果又有进 程诸求I/O操作,则将产生一个默认的6毫秒猜测时间,猜测下一个进程请求 I/O是要干什么的。这对于随机读取会造成比较大的延时,对数据库应用很糟 糕,而对于Web Server等则会表现的不错。这个算法也可以简单理解为而向低 速磁盘的,因为那个〃猜测"实际上的目的是为了减少磁头移动时间。因此这种 算法更加适合顺序读写的应用程序。这个可以用来调整的内核参数有 antic_expire, read_expire和 write_expire.
linux中10调度方法的查看和设置的方法
查看当前 10 cat/sys/block/{DEVICE-NAME}/queue/scheduler cat/sys/block/sd*/queue/scheduler
例:输出结果如下
noop anticipatory deadline[cfq]
设置当前 10 echo{SCHEDULER-NAME}/sys/block/{DEVICE-NAME} /queue/scheduler echo noop/sys/block/hda/queue/scheduler
对10调度使用的建议
Deadline I/O scheduler
在这个屮deadline调度算法通过降低性能而获得更短的等待时间,它使用 轮询的调度器,简洁小巧,提供了最小的读取延迟和尚佳的吞吐量,特别适合于读 取较多的环境(比如数据库,Oracle 10G之类)
Anticipatory I/O scheduler anticipatory算法通过增加等待时间来获 得更高的性能,假设一个块设备只有一个物理查找磁头(例如一个单独的SATA 硬盘),将多个随机的小写入流合并成一个大写入流(相当于给随机读写变顺序读 写),使用这个原理来使用读取写入的延时换取最大的读取写入吞吐量.适用于大 多数环境,特别是读取写入较多的环境,比如文件服务器,Web应用,App等应用我 们可以采纳as调度.后而我会教大家怎么调这个的合并的等待时间。
CFQ I/O scheduler
这个是对所有因素也都做了折屮而尽量获得公平性,使用QoS策略为所有任 务分配等量的带宽,避免进程被饿死并实现/较低的延迟,可以认为是上述两种 调度器的折屮.适用于有大景进程的多用户系统
Anticipatory 调节
根据上而的内容,我们算法屮可能用的最多的就是Anticipatory的算法了, 会根据时间来多排一些内容在写,所以下而讲讲这个参数可以调的部分。
除了算法修改成这个算法外,影响它的还有磁盘队列长度/sys/block/sda/queue/nr_requests默认只有128个队列,可以提高到 512个。会更加占用内存,但能更加多的合并读写操作,速度变慢,但能读写更加多的量等待时间/sys/block/sda/queue/iosched/antic_expire 读取附近产生的新诸时等 待多长时间对读优化的参数/sys/block/sda/queue/read_ahead_kb这个参数对顺序读非常有用,意思是,一次提前读多少内容,无论实际需 要多少。默认一次读128kb远小于要读的,设置大些对读大文件非常有用,可 以有效的减少读seek的次数,这个参数可以使用blockdev - setra来设置, setra设置的是多少个扇区,所以实际的字节是除以2,比如设置512,实阮是 读256个字节。
几个非常有效的IO调度调节的内核参数
/proc/sys/vm/dirty_ratio
这个参数控制文件系统的文件系统写缓冲区的大小,单位是百分比,表示 系统内存的百分比,表示当写缓冲使用到系统内存多少的时候,开始向磁盘写 出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极大提高系统的 写性能。但是,当你需要持续、恒定的写入场合时,应该降低其数值,一般启 动上缺省是10。下而是增大的方法:echo’40' /proc/sys/vm/dirty_ratio
/proc/sys/vm/dirty_background_ratio
这个参数控制文件系统的pdflush进程,在何时刷新磁盘。单位是百分比, 表示系统内存的百分比,意姐是当写缓冲使用到系统内存多少的时候,pdflush 开始向磁盘写出数据。增大之会使用更多系统内存用于磁盘写缓冲,也可以极 大提高系统的写性能。但是,当你需要持续、恒定的写入场合时,应该降低其 数值,一般启动上缺省是5。下而是增大的方法:echo’20'
/proc/sys/vm/dirty_background_ratio
/proc/sys/vm/dirty_writeback_centisecs
这个参数控制内核的脏数据刷新进程pdflush的运行间隔。单位是1/100 秒。缺省数值是500,也就是5秒。如果你的系统是持续地写入动作,那么实 阮上还是降低这个数值比较好,这样可以把尖峰的写操作削平成多次写操作。 设置方法如下:echo’ 200' /proc/sys/vm/dirty_writeback_centisecs 如果你 的系统是短期地尖峰式的写操作,并11写入数据不大(几十M/次)II内存有比较多富裕,那么应该增大此数值:echo’1000' /proc/sys/vm/dirty_writeback_centisecs
/proc/sys/vm/dirty_expire_centisecs
这个参数声明Linux内核写缓冲区里而的数据多"旧"了之后,pdflush进 程就开始考虑写到磁盘中去。单位是1/100秒。缺省是30000,也就是30秒的 数据就算旧了,将会刷新磁盘。对于特别重载的写操作来说,这个值适当缩小 也是好的,但也不能缩小太多,因为缩小太多也会导致10提高太快。建议设置 为1500,也就是15秒算旧。echo’1500'
/proc/sys/vm/dirty_expire_centisecs当然,如果你的系统内存比较大,并 且写入模式是间歇式的,并II每次写入的数据不大(比如几十M),那么这个值 还是大些的好。
配置安装DRBD;
前提:
1)本配置共有两个测试节点,分别node1.firefox.com和node2.firefox.com,相的IP地址分别为172.16.100.7和172.16.100.8;
2)node1和node2两个节点上各提供了一个大小相同的分区作为drbd设备;我们这里为在两个节点上均为/dev/sda5,大小为512M;
3)系统为CentOS 6.5,x86_64平台;
1、准备工作
两个节点的主机名称和对应的IP地址解析服务可以正常工作,且每个节点的主机名称需要跟"uname -n“命令的结果保持一致;因此,需要保证两个节点上的/etc/hosts文件均为下面的内容:
172.16.249.7 node1.firefox.com node1
172.16.249.8 node2.firefox.com node2
为了使得重新启动系统后仍能保持如上的主机名称,还分别需要在各节点执行类似如下的命令:
Node1: # sed -i 's@\(HOSTNAME=\).*@\1node1.firefox.com@g' # hostname node1.firefox.com Node2: # sed -i 's@\(HOSTNAME=\).*@\1node2.firefox.com@g' # hostname node2.firefox.com
2、安装软件包
drbd共有两部分组成:内核模块和用户空间的管理工具。其中drbd内核模块代码已经整合进Linux内核2.6.33以后的版本中,因此,如果您的内核版本高于此版本的话,你只需要安装管理工具即可;否则,您需要同时安装内核模块和管理工具两个软件包,并且此两者的版本号一定要保持对应。
目前适用CentOS 5的drbd版本主要有8.0、8.2、8.3三个版本,其对应的rpm包的名字分别为drbd, drbd82和drbd83,对应的内核模块的名字分别为kmod-drbd, kmod-drbd82和kmod-drbd83。而适用于CentOS 6的版本为8.4,其对应的rpm包为drbd和drbd-kmdl,但在实际选用时,要切记两点:drbd和drbd-kmdl的版本要对应;另一个是drbd-kmdl的版本要与当前系统的内容版本相对应。各版本的功能和配置等略有差异;我们实验所用的平台为x86_64且系统为CentOS 6.5,因此需要同时安装内核模块和管理工具。我们这里选用最新的8.4的版本(drbd-8.4.3-33.el6.x86_64.rpm和drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm),下载地址为ftp://rpmfind.net/linux/atrpms/,请按照需要下载。
实际使用中,您需要根据自己的系统平台等下载符合您需要的软件包版本,这里不提供各版本的下载地址。
下载完成后直接安装即可:
# rpm -ivh drbd-8.4.3-33.el6.x86_64.rpm drbd-kmdl-2.6.32-431.el6-8.4.3-33.el6.x86_64.rpm
3、配置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.firefox.com上完成。
1 新建磁盘分区;
[root@node1 ~]# fdisk /dev/sda WARNING: DOS-compatible mode is deprecated. It's strongly recommended to switch off the mode (command 'c') and change display units to sectors (command 'u'). Command (m for help): p Disk /dev/sda: 68.7 GB, 68719476736 bytes 255 heads, 63 sectors/track, 8354 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00080f2b Device Boot Start End Blocks Id System /dev/sda1 * 1 26 204800 83 Linux Partition 1 does not end on cylinder boundary. /dev/sda2 26 7859 62914560 8e Linux LVM Command (m for help): p Disk /dev/sda: 68.7 GB, 68719476736 bytes 255 heads, 63 sectors/track, 8354 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00080f2b Device Boot Start End Blocks Id System /dev/sda1 * 1 26 204800 83 Linux Partition 1 does not end on cylinder boundary. /dev/sda2 26 7859 62914560 8e Linux LVM Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 3 First cylinder (7859-8354, default 7859): Using default value 7859 Last cylinder, +cylinders or +size{K,M,G} (7859-8354, default 8354): Using default value 8354 Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 16: Device or resource busy. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) Syncing disks. [root@node1 ~]# partx -a /dev/sda BLKPG: Device or resource busy error adding partition 1 BLKPG: Device or resource busy error adding partition 2 [root@node1 ~]# kpartx -af /dev/sda device-mapper: reload ioctl on sda1 failed: Invalid argument create/reload failed on sda1 device-mapper: reload ioctl on sda2 failed: Invalid argument create/reload failed on sda2 device-mapper: reload ioctl on sda3 failed: Invalid argument create/reload failed on sda3
2 配置/etc/drbd.d/global-common.conf
global { usage-count no; # minor-count dialog-refresh disable-ip-verification } common { 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 #wfc-timeout 120; #degr-wfc-timeout 60; } 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 { protocol C; cram-hmac-alg "sha1"; shared-secret "drbd.firefox.com"; # 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 1000M; } }
3、定义一个资源/etc/drbd.d/mystore.res,内容如下:
# cat mystore.res resource mystore { on node1.firefox.com { device /dev/drbd0; disk /dev/sda3; address 172.16.249.7:7789; meta-disk internal; } on node2.firefox.com { device /dev/drbd0; disk /dev/sda3; address 172.16.249.8:7789; meta-disk internal; } }
以上文件在两个节点上必须相同,因此,可以基于ssh将刚才配置的文件全部同步至另外一个节点。
# scp -p /etc/drbd.d/* node2:/etc/drbd.d/
4、在两个节点上初始化已定义的资源并启动服务:
1)初始化资源,在Node1和Node2上分别执行:
# drbdadm create-md mystore
2)启动服务,在Node1和Node2上分别执行:
/etc/init.d/drbd start
3)查看启动状态:
# cat /proc/drbd version: 8.3.8 (api:88/proto:86-94) GIT-hash: d78846e52224fd00562f7c225bcc25b2d422321d build by [email protected], 2010-06-04 08:04:16 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:b oos:505964 也可以使用drbd-overview命令来查看: # drbd-overview 0:web Connected Secondary/Secondary Inconsistent/Inconsistent C r----
从上面的信息中可以看出此时两个节点均处于Secondary状态。于是,我们接下来需要将其中一个节点设置为Primary。在要设置为Primary的节点上执行如下命令: # drbdadm primary --force mystore 注: 也可以在要设置为Primary的节点上使用如下命令来设置主节点: # drbdadm -- --overwrite-data-of-peer primary mystore
而后再次查看状态,可以发现数据同步过程已经开始: # drbd-overview 0:web SyncSource Primary/Secondary UpToDate/Inconsistent C r---- [============>.......] sync'ed: 66.2% (172140/505964)K delay_probe: 35 等数据同步完成以后再次查看状态,可以发现节点已经牌实时状态,且节点已经有了主次: # drbd-overview 0:web Connected Primary/Secondary UpToDate/UpToDate C r----
5、创建文件系统
文件系统的挂载只能在Primary节点进行,因此,也只有在设置了主节点后才能对drbd设备进行格式化:
[root@node1 drbd.d]# mke2fs -t ext4 /dev/drbd0 mke2fs 1.41.12 (17-May-2010) Filesystem label=DRBD OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 248992 inodes, 995740 blocks 49787 blocks (5.00%) reserved forthe super user First data block=0 Maximum filesystem blocks=1023410176 31 block groups 32768 blocks per group, 32768 fragments per group 8032 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736 Writing inode tables: done Creating journal (16384 blocks): done Writing superblocks and filesystem accounting information: done This filesystem will be automatically checked every 22 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. root@node1 drbd.d]# mkdir /mnt/drbd [root@node1 drbd.d]# mount /dev/drbd0 /mnt/drbd
5、切换Primary和Secondary节点
对主Primary/Secondary模型的drbd服务来讲,在某个时刻只能有一个节点为Primary,因此,要切换两个节点的角色,只能在先将原有的Primary节点设置为Secondary后,才能原来的Secondary节点设置为Primary:
Node1: # cp -r /etc/drbd.* /mnt/drbd # umount /mnt/drbd # drbdadm secondary mystore 查看状态: # drbd-overview 0:web Connected Secondary/Secondary UpToDate/UpToDate C r----
Node2: # drbdadm primary web # drbd-overview 0:web Connected Primary/Secondary UpToDate/UpToDate C r---- # mkdir /mnt/drbd # mount /dev/drbd0 /mnt/drbd [root@node2 ~]# cd /mnt/drbd/ [root@node2 drbd]# ls drbd.conf drbd.d lost+found
drbd 8.4中第一次设置某节点成为主节点的命令
# drbdadm primary --force resource
配置资源双主模型的示例:
resource mydrbd { net { protocol C; allow-two-primaries yes; } startup { become-primary-on both; } disk { fencing resource-and-stonith; } handlers { # Make sure the other node is confirmed # dead after this! outdate-peer "/sbin/kill-other-node.sh"; } on node1.firefox.com { device /dev/drbd0; disk /dev/vg0/mydrbd; address 172.16.200.11:7789; meta-disk internal; } on node2.firefox.com { device /dev/drbd0; disk /dev/vg0/mydrbd; address 172.16.200.12:7789; meta-disk internal; } }