嗯,有些是直接摘自别人的博客,更多的是manpage,不违法吧。我的就没什么版权声明了,GPL

DistributedReplicatedBlockDevice(DRBD)是一种基于软件的,无共享,复制的存储解决方案,在服务器之间的对块设备(硬盘,分区,逻辑卷等)进行镜像。DRBD工作在内核当中的,类

似于一种驱动模块。DRBD工作的位置在文件系统的buffercache和磁盘调度器之间,通过tcp/ip发给另外一台主机到对方的tcp/ip最终发送给对方的drbd,再由对方的drbd存储在本地对应磁

盘上,类似于一个基于网络的RAID-1。

DRBD需要构建在底层设备之上,然后构建出一个块设备出来。对于用户来说,一个DRBD设备,就像是一块物理的磁盘,可以在上面内创建文件系统。DRBD所支持的底层设备有以下这些类:
1、一个磁盘,或者是磁盘的某一个分区;
2、一个softraid设备;
3、一个LVM的逻辑卷;
4、一个EVMS(EnterpriseVolumeManagementSystem,企业卷管理系统)的卷;
5、其他任何的块设备。


由于单机文件系统的限制,drbd只能在主节点上被挂载。
Inspiteofthislimitation,therearestillafewwaystoaccessthedataonthesecondnode:

UseDRBDonlogicalvolumesanduseLVM'scapabilitiestotakesnapshotsonthestandbynode,andaccessthedataviathesnapshot.
DRBD'sprimary-primarymodewithashareddiskfilesystem(GFS,OCFS2).Thesesystemsareverysensitivetofailuresofthereplicationnetwork.


DRBD的配置:
范例:
环境:
1、两个节点,分别为node1(10.0.9.1),node2(10.0.9.2),这里node11,node2即是主机名,和'uname-n'的输出相同。
2、每个节点各提供一个大小精确相同的块设备(我这里使用的是一个lv),分别为/dev/centos_vg/web和/dev/myvg/web,均为100M。
3、我不知道是不是要求drbd的版本一致,我的两台虚拟机操作系统版本和drbd的版本都是一致的。centos6.4x86_64

操作步骤:
1、确保两台drbd的主机时间是同步的,这个要求跟配置集群节点是相同的。
2、两个节点的主机名应当可以正确解析,且主机名应该和'uname-n'的结果相同,解析出来的IP应当是用于两个节点之间通信、同步数据的IP。建议配置hosts文件,比DNS靠谱。
3、安装软件包
drbd共有两部分组成:内核模块和用户空间的管理工具。其中drbd内核模块代码已经整合进Linux内核2.6.33以后的版本中,因此,如果您的内核版本高于此版本的话,你只需要安装

管理工具即可;否则,您需要同时安装内核模块和管理工具两个软件包,并且模块和管理工具的版本号一定要保持对应。
由于我所使用的centos内核不自带drbd模块,所以需要安装。

目前适用CentOS5的drbd版本主要有8.0、8.2、8.3三个版本,其对应的rpm包的名字分别为drbd,drbd82和drbd83,对应的内核模块的名字分别为kmod-drbd,kmod-drbd82和kmod-

drbd83。而适用于CentOS6的版本为8.4,其对应的rpm包为drbd和drbd-kmdl,但在实际选用时,要切记两点:drbd和drbd-kmdl的版本要对应;另一个是drbd-kmdl的版本要与当前系统的内核

版本相对应。我这里选用8.4的版本(drbd-8.4.3-33.el6.x86_64.rpm和drbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm),下载地址为ftp://rpmfind.net/linux/atrpms/
下载完成后直接安装即可:
#rpm-ivhdrbd-8.4.3-33.el6.x86_64.rpmdrbd-kmdl-2.6.32-358.el6-8.4.3-33.el6.x86_64.rpm

4、配置
drbd的主配置文件为/etc/drbd.conf.内容是:
include"drbd.d/global_common.conf";
include"drbd.d/*.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资源,资源在定义时必须为其命名,名字可以由非空白的ASCII字符组成。每一个资源段的定义中要包含两个(或更多)host子段,以定义此资源关联至的

节点。

两个节点关于同一drbd资源的配置应当完全相同,之所以这么说,是考虑到可能存在存在多个drbd节点、多个drbd资源的情况:比如node1上有资源A,node2上有资源B,C,node3上有

资源C。这里且不考虑这种情况
先在node1上配置:
global_common.conf文件

global {
usage-count no;
# minor-count dialog-refresh disable-ip-verification
}
common {
protocol C;
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   "mydrbd";
# 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 30M;
}
}

web.res的内容:

resource web {
meta-disk internal;
on node1 {
device /dev/drbd0;  #等价于 device minor 0
disk    /dev/centos_vg/web;
address 10.0.9.1:7789;
}
on node2 {
device /dev/drbd0;  #在node2上生成的 drbd 设备名
disk    /dev/myvg/web;  #使用node2上哪个块设备作为drbd的底层设备
address 10.0.9.2:7789;  #node2使用该socket与对方节点通信
}
}

也可以使用floatingnode-ip的形式代替onnode-name的形式:
这里是manpage中的一个示例:

resourcer2{
protocolC;
deviceminor2;
disk/dev/sda7;
meta-diskinternal;

#shortform,device,diskandmeta-diskinherited
floating10.1.1.31:7802;

#longerform,onlydeviceinherited
floating10.1.1.32:7802{
disk/dev/sdb;
meta-disk/dev/sdc8;
}
}

5、将以上配置复制到对方节点
6、初始化资源,分别在两边节点上创建/var/lib/drbd目录(该目录用于放置类似drbd-minor-0.lkbd的文件),执行:
#drbdadmcreate-mdweb
7、启动drbd服务
#/etc/init.d/drbdstart

8、查看启动状态
#cat/proc/drbd
或者
#drbd-overview
此时两个节点均处于secondary状态
9、根据需要将其中一个节点设置为主节点,在需要成为主节点的机器上执行
#drbdadmprimary--forceweb
查看drbd的状态,从节点会从主节点进行逐位同步
10、在主节点上,为drbd设备创建文件系统(也可以将drbd设备创建成LVM设备),然后挂载
drbd集群中,只有主节点是可以读的,从节点的drbd设备是不能读写的,所有节点的drbd底层设备上不能执行任何文件系统操作(在drbd在上面运行时),包括dumpe2fs等命令。

11、切换主从节点
在主节点上:
将挂载的drbd设备卸载,然后执行
drbdadmsecondaryweb
在从节点上:
drbdadmprimaryweb
然后挂载drbd设备,注意,不要格式化,因为drbd从设备在同步的时候是逐位进行同步的,同步的时候就已经格式化了。

关于配置的一些解释:

protocolprot-id
OntheTCP/IPlinkthespecifiedprotocolisused.ValidprotocolspecifiersareA,B,andC.

ProtocolA:writeIOisreportedascompleted,ifithasreachedlocaldiskandlocalTCPsend
buffer.

ProtocolB:writeIOisreportedascompleted,ifithasreachedlocaldiskandremotebuffer
cache.

ProtocolC:writeIOisreportedascompleted,ifithasreachedbothlocalandremotedisk.

handlers:inthissectionyoucandefinehandlers(executables)thatarestartedbytheDRBDsysteminresponsetocertainevents

devicenameminornr
Thenameoftheblockdevicenodeoftheresourcebeingdescribed.Youmustusethisdevicewith
yourapplication(filesystem)andyoumustnotusethelowlevelblockdevicewhichisspecified
withthediskparameter.

Onecanetheromitthenameorminorandtheminornumber.Ifyouomitthenameadefaultof
/dev/drbdminorwillbeused.

Udevwillcreateadditionalsymlinksin/dev/drbd/by-resand/dev/drbd/by-disk.

diskname
DRBDusesthisblockdevicetoactuallystoreandretrievethedata.Neveraccesssuchadevice
whileDRBDisrunningontopofit.Thisalsoholdstruefordumpe2fs(8)andsimilarcommands.

addressAFaddr:port
AresourceneedsoneIPaddressperdevice,whichisusedtowaitforincomingconnectionsfrom
thepartnerdevicerespectivelytoreachthepartnerdevice.AFmustbeoneofipv4,ipv6,
ssocksorsdp(forcompatibilityreasonssciisanaliasforssocks).ItmaybeomitedforIPv4
addresses.TheactualIPv6addressthatfollowstheipv6keywordmustbeplacedinsidebrackets:
ipv6[fd01:2345:6789:abcd::1]:7800.

EachDRBDresourceneedsaTCPportwhichisusedtoconnecttothenode'spartnerdevice.Two
differentDRBDresourcesmaynotusethesameaddr:portcombinationonthesamenode.


on-io-errorhandler
istaken,ifthelowerleveldevicereportsio-errorstotheupperlayers.

handlermaybepass_on,call-local-io-errorordetach.

pass_on:Thenodedowngradesthediskstatustoinconsistent,markstheerroneousblockas
inconsistentinthebitmapandretriestheIOontheremotenode.

call-local-io-error:Callthehandlerscriptlocal-io-error.

detach:Thenodedropsitslowleveldevice,andcontinuesindisklessmode.

ping-inttime
IftheTCP/IPconnectionlinkingaDRBDdevicepairisidleformorethantimeseconds,DRBDwill
generateakeep-alivepackettocheckifitspartnerisstillalive.Thedefaultis10seconds,
theunitis1second.

ping-timeouttime
Thetimethepeerhastimetoanswertoakeep-alivepacket.Incasethepeer'sreplyisnot
receivedwithinthistimeperiod,itisconsideredasdead.Thedefaultvalueis500ms,the
defaultunitaretenthsofasecond.

become-primary-onnode-name
Setsonwhichnodethedeviceshouldbepromotedtoprimaryroleby
theinitscript.Thenode-namemighteitherbeahostnameorthe
keywordboth.Whenthisoptionisnotsetthedevicesstayin
secondaryroleonbothnodes.Usuallyonedelegatestherole
assignmenttoaclustermanager(e.g.heartbeat).
必须在common的startup中设置,若在资源中设置似乎会报错

verify-alghash-alg
Duringonlineverification(asinitiatedbytheverifysub-command),
ratherthandoingabit-wisecomparison,DRBDappliesahash
functiontothecontentsofeveryblockbeingverified,andcompares
thathashwiththepeer.Thisoptiondefinesthehashalgorithm
beingusedforthatpurpose.Itcanbesettoanyofthekernel's
datadigestalgorithms.Inatypicalkernelconfigurationyoushould
haveatleastoneofmd5,sha1,andcrc32cavailable.Bydefault
thisisnotenabled;youmustsetthisoptionexplicitlyinorderto
beabletouseon-linedeviceverification.

cram-hmac-alg
YouneedtospecifytheHMACalgorithmtoenablepeerauthentication
atall.Youarestronglyencouragedtousepeerauthentication.The
HMACalgorithmwillbeusedforthechallengeresponse
authenticationofthepeer.Youmayspecifyanydigestalgorithm
thatisnamedin/proc/crypto.

shared-secret
Thesharedsecretusedinpeerauthentication.Maybeupto64
characters.Notethatpeerauthenticationisdisabledaslongasno
cram-hmac-alg(seeabove)isspecified.

resync-raterate
ToensureasmoothoperationoftheapplicationontopofDRBD,it
ispossibletolimitthebandwidthwhichmaybeusedbybackground
synchronizations.Thedefaultis250KB/sec,thedefaultunitis
KB/sec.OptionalsuffixesK,M,Gareallowed.

drbdadm常用选项和子命令
-d,--dry-run
-c,--config-file

attach
AttachesalocalbackingblockdevicetotheDRBDresource'sdevice.
detach
RemovesthebackingstoragedevicefromaDRBDresource'sdevice.
connect
Setsupthenetworkconfigurationoftheresource'sdevice.Ifthepeerdeviceisalready
configured,thetwoDRBDdeviceswillconnect.Iftherearemorethantwohostsectionsinthe
resourceyouneedtousethe--peeroptiontoselectthepeeryouwanttoconnectto.
disconnect
Removesthenetworkconfigurationfromtheresource.ThedevicewillthengointoStandAlone
state.
up
Isashortcutforattachandconnect.

down
Isashortcutfordisconnectanddetach.
syncer
Loadstheresynchronizationparametersintothedevice.
verify
Startsonlineverify.Duringonlineverify,dataonbothnodesiscomparedforequality.See
/proc/drbdforonlineverifyprogress.Ifout-of-syncblocksarefound,theyarenot
resynchronizedautomatically.Todothat,disconnectandconnecttheresourcewhenverification
hascompleted.
pause-sync
Temporarilysuspendanongoingresynchronizationbysettingthelocalpauseflag.Resynconly
progressesifneitherthelocalnortheremotepauseflagisset.Itmightbedesirableto
postponeDRBD'sresynchronizationuntilafteranyresynchronizationofthebackingstorage'sRAID
setup.
resume-sync
Unsetthelocalsyncpauseflag.
dstate
Showthecurrentstateofthebackingstoragedevices.(local/peer)

hidden-commands
Showsallcommandsundocumentedonpurpose.

常用命令:
drbdadmcreate-mdresource_name#初始化drbd资源
drbdadmverifyresource_name#启动在线校验
drbdsetup/dev/drbd0syncer-r100M#临时设置re-synchronization的速度为100M
drbdadmadjustresource_name#恢复drbd的re-synchronization的速度会配置文件中设置的值
cat/proc/drbd#查看drbd的状态
drbdadmprimary[--force]resource_name#[强制]提升当前节点为resource_name的主节点
drbdadmsecondary<resource_name>#用于在卸载drbd设备后将当前节点降级为resource_name的从节点
drbdadmdump#Justparsetheconfigurationfileanddumpittostdout.可用于检查语法
drbdadmdisconnect<resource_name>
drbdadmdetach<resource_name>


splitbrain脑裂
splitbrain实际上是指在某种情况下,造成drbd的两个节点断开连接,都以primary的身份来运行。当drbd某primary节点连接对方节点准备发送信息的时候如果发现对方也是primary状态,

那么会立刻自行断开连接,并认定当前已经发生splitbrain了,这时候他会在系统日志中记录以下信息:“Split-Braindetected,droppingconnection!”当发生splitbrain之后,如果查看

连接状态,其中至少会有一个是StandAlone状态,另外一个可能也是StandAlone(如果是同时发现splitbrain状态),也有可能是WFConnection的状态。
如果我们在配置文件中配置了自动解决splitbrain(好像linbit不推荐这样做),drbd会自行解决splitbrain问题,可通过如下策略进行配置。
Discardingmodificationsmadeonthe“younger”primary。在这种模式下,当网络重新建立连接并且发现了裂脑,DRBD会丢弃最后切换到主节点上的主机所修改的数据。
Discardingmodificationsmadeonthe“older”primary.在这种模式下,当网络重新建立连接并且发现了裂脑,DRBD丢弃首先切换到主节点上的主机后所修改的数据。
Discardingmodificationsontheprimarywithfewerchanges.在这种模式下,当网络重新建立连接并且发现了裂脑,DRBD会比较两台主机之间修改的数据量,并丢弃修改数据量较少的主

机上的所有数据。
Gracefulrecoveryfromsplitbrainifonehosthashadnointermediatechanges.在这种模式下,如果其中一个主机在脑裂期间并没有数据修改,DRBD会自动重新进行数据同步,并宣

布脑裂问题已解决。(这种情况几乎不可能存在)
注意:自动裂脑自动修复能不能被接受取决于个人应用。考虑建立一个DRBD的例子库。在“丢弃修改比较少的主节点的修改”兴许对web应用好过数据库应用。与此相反,财务的数据库则是对

于任何修改的丢失都是不能容忍的,这就需要不管在什么情况下都需要手工修复裂脑问题。因此需要在启用裂脑自动修复前考虑你的应用情况。
如果没有配置splitbrain自动解决方案,我们可以手动解决。首先我们必须要确定哪一边应该作为解决问题后的primary,一旦确定好这一点,那么我们同时也就确定接受丢失在split

brain之后另外一个节点上面所做的所有数据变更了。当这些确定下来后,我们就可以通过以下操作来恢复了:
1、首先在确定要作为secondary的节点上面切换成secondary并放弃该资源的数据:
drbdadmsecondaryresource_name
drbdadm—–discard-my-dataconnectresource_name
2、在要作为primary的节点重新连接secondary(如果这个节点当前的连接状态为WFConnection的话,可以省略)
drbdadmconnectresource_name
当作完这些动作之后,从新的primary到secondary的re-synchnorisation会自动开始。

metadata
DRBD将数据的各种信息块保存在一个专用的区域里,这些metadata包括了
a,DRBD设备的大小
b,产生的标识
c,活动日志
d,快速同步的位图
metadata的存储方式有内部和外部两种方式,使用哪种配置都是在资源配置中定义的
内部metadata
内部metadata存放在同一块硬盘或分区的最后的位置上
优点:metadata和数据是紧密联系在一起的,如果硬盘损坏,metadata同样就没有了,同样在恢复的时候,metadata也会一起被恢复回来
缺点:metadata和数据在同一块硬盘上,对于写操作的吞吐量会带来负面的影响,因为应用程序的写请求会触发metadata的更新,这样写操作就会造成两次额外的磁头读写移动。
外部metadata
外部的metadata存放在和数据磁盘分开的独立的块设备上
优点:对于一些写操作可以对一些潜在的行为提供一些改进
缺点:metadata和数据不是联系在一起的,所以如果数据盘出现故障,在更换新盘的时候就需要认为的干预操作来进行现有node对心硬盘的同步了
如果硬盘上有数据,并且硬盘或者分区不支持扩展,或者现有的文件系统不支持shrinking,那就必须使用外部metadata这种方式了。

disk在common段中是一个子section,定义的是关于drdb设备的一些参数,而在resource段中是一个配置参数,定义用于提供drbd设备的底层块设备名称


参考文档:

http://www.drbd.org/docs/introduction/
http://czmmiao.iteye.com/blog/1773079
man5drbd.conf
mandrbdadm
DRBDUser'sGuide