一般我们的机房要实现前端服务的高可用性,就需要共享存储。就我现在学习过程中所了解到的有几种解决办法,如:NFS,CIFS,ISCSI,DRBD。这里我们就说说DRBD是怎么回事,又怎么使用。
一、介绍。
我们还是先来看下在存储方面有哪几种类型的存储设备。
DAS:Direct Attached Storage(直接附加存储),表示直接连在主机主板上的存储方式,如:连到主机上的SATA存储,SCSI存储,IDE存储,USB存储。这些都是啦。可以说就是直接由主板供电的。服务与存储在一起使用。然后我们通过rsync+inotify来同步数据给另一台服务器。这台服务器挂了,服务和存储就转到另一台服务器上。因为rsync只能单方向的同步,所以只能同时一台服务器提供服务。
NAS:Network Attached Storage(网络附加存储),表示连在网络上,可以提供存储的,也就是网络存储器,是一些可独立工作的文件服务器。其于文件级别,客户端可以挂载使用。我们用软件可以实现的,如:NFS,cifs。
这种文件级别的存储易于管理,但是性能就很一般了。受限于网络和存储I/O的能力。
SAN:Storage Area Network(存储区域网络),简单的讲就是DAS的延伸(SAN封装的是SCSI协议,所以不单单是DAS的延伸),实际存储被丢到了另一个地方,所以就被称为存储区域-网络。当然上面说的简单,直接丢出去肯定是不行的。大约过程就是:本地的数据经过文件系统处理以后成为可以直接存储到硬盘上的数据块以后,没有存储到磁盘,而是由某种机制把数据封装以后发送出去。而存储设备收到数据以后再由这种机制拆封以后,直接存储到硬盘上。这是块级别的存储,在客户端是可以当成本地的磁盘来处理的,分区格式化之类的。软件可以实现的,如:IP SAN(iscsi)。
专业的FC-SAN成本太高,一般要用IP-SAN也就是iscsi来实现,同样受限于网络和存储I/O的能力,只不过处理能力比NAS高。
NFS与ISCSI的不同之处(因为只用过这种软件的,别的不敢妄加评论):
1。NFS是文件级别的存储,客户端调用文件API把数据发给存储方,存储服务器要经过文件系统的处理,要做的动作比较多,开销自然也就大。而ISCSI是把数据直接拿来存储了,开销小。
2。NFS因为存储服务器是台独立的设备,而且存储过程也是可以控制的,所以多台主机可以同时存储。而ISCSI因为存储非常底层,存储是不受存储服务器控制的,如果同时存储同一个文件,会发生I/O错误或者文件数据丢失,要么就是文件系统崩溃。可以通过集群文件系统解决,但也不能太多节点,一般不要超过16个节点。非常影响性能。
好啦,我们不是来说iscsi的,来说说DRBD吧:官方网站:http://drbd.linbit.com/
DRBD,我觉得也是一种IP-SAN的实现,也是块级别的存储,传输的也是磁盘块数据,只不过不是封装SCSI协议来实现的,可以理解为是网络版的Read1,通过在磁盘块级别的数据同步。也可以说是DAS的延伸,因为也是直接连在本地,只不过是复制了一份给另一节点而已。这就看看问题的角度了。
在发生一个节点挂了的清况下,另一节点就可以开始工作。而且存储也同时实现了高可用。
(官方图)
如上面这张图看到的,DRBD模块就工作在BUFFER和DESK SCHED之间,DRBD模块在收到数据以后复制成两份,一份向下,一份交由TCP/IP协议封装报文,通过网络发送到对端以后,TCP拆封发现是DRBD的数据,交由DRBD模块,DRBD向下发送,最终存储到磁盘。
也正是由于这种机制,一般情况下DRBD只有两个节点。
而这种一方的DRBD向另一方的DRBD发送数据,当然要有确认机制了,要不然谁知道对端是否存储成功了。确认机制有三种,在DRBD的表示中是三个协议:A,B,C。如下:
A:称为异步模式。数据到达本地的TCP/IP队列以后,返回确认。
B:半同步模式。数据在到达对端的TCP/IP队列以后,返回确认。
C:同步模式。 数据在对端磁盘存储成功以后,返回确认。一般在宽带可以的情况下,都用这个,保证数据的一致性。
DRBD有两种工作模式
主从模型(也是我们这里要说的)。我们知道这种块级别的存储,对端对数据是不可控的,如果双方都同时操作文件。可能会发生我修改了文件,在还没有写入磁盘的时候,对端的删除文件操作过来了,duang文件没了,这时会怎么样。而且对端也是同样的情况发生。双方同时修改,双方的文件系统可能都会崩溃。
双主模型。我这两台服务器同时提供了服务,这样就要用全局锁了,一方在写入的时候,另一方不可以写,这就是集群文件系统了。这里就不多做介绍了。
介绍下工具:
在上面那张图中,service是在用户空间的,以下都是在内核空间中。drbd就是工作在内核中的,而所对应的,我们要想让它工作起来,就要安装用户空间工具。
在linux内核2.6.33版本以下,内核中是没有drbd这个功能的。我们可以给linux内核打补丁,重新编译。或者可以简单点,安装别人编译好的内核模块。以下就是直接安装模块的作法。
在CentOS5的版本中主要有8.0、8.2和8.3这三个版本,对应用户空间管理工且的rpm包是drbd、drbd82和drbd83,内核模块的rpm包是kmod-drbd,、kmod-drbd82和kmod-drbd83。
在CentOS6的版本中适用的有8.4,其对应的rpm包管理工具为drbd,内核模块rpm包为drbd-kmdl。
注意:我们安装的是内核模块,所以drbd的内核模块版本要与内核版本严格对应。而管理工具则又要去drbd版本对应。我们下载的时候,rpm包上面是有两个号的,一个是对应的内核版本,一个是工具的版本。
环境介绍:
内核版本:2.6.32-431.el6.x86_64
系统:CentOS6.5_x86_64
安装包下载路径:ftp://rpmfind.net/linux/atrpms/el6-x86_64/atrpms/stable/
对应于我这里内核2.6.32-431的是最下面的两个(严格对应,发行号最好也要一样),一个drbd的版本是8.3,一个是8.4。这里当然要用新的了,而对应于8.4版本的用户空间管理工具是最上面的第二个。
[root@node2 ~]# ls drbd 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@node2 ~]#
二、安装
准备工作
双机时间同步,主机名可以相互解析。时间同步可以安装ntp服务来解决,主机名可以直接在hosts里面添加,最好不要用DNS,DNS单点故障问题。
在linux内核2.6.33以后的版本中,drbd已经整合进了内核中。所以只要看好drbd的版本并安装对应的用户空间工具就可以了。如果是之前的版本,比如我们用的CentOS6.5,可以去ftp://rpmfind.net/linux/atrpms/这里下载。
然后直接在两台主机上rpm安装就可以,这个倒是没有什么依赖关系。
[root@node2 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@node2 drbd]# rpm -ivh drbd* warning: drbd-8.4.3-33.el6.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 66534c2b: NOKEY Preparing... ########################################### [100%] 1:drbd-kmdl-2.6.32-431.el########################################### [ 50%] 2:drbd ########################################### [100%]
安装drbd这个包,也就是管理工具包,会生成三个管理命令:
/sbin/drbdadm #常用到的就是这个。 /sbin/drbdmeta #用来管理DRBD的元数据 /sbin/drbdsetup #不好用,一般用不到,大部分功能drbdadm都有。
安装drbd-kmdl,也就是内核模块包
[root@node1 drbd]# rpm -ql drbd-kmdl-2.6.32-431.el6 /lib/modules/2.6.32-431.el6.x86_64/updates /lib/modules/2.6.32-431.el6.x86_64/updates/drbd.ko #模块 /lib/modules/2.6.32-431.el6.x86_64/updates/drivers /lib/modules/2.6.32-431.el6.x86_64/updates/drivers/block [root@node1 drbd]#
安装完成以后可能要在两个节点上各自执行一下depmod来重新生成一下 modules.dep。这个文件里面是模块的列表,和各个模块的依赖关系。
配置使用
所有的配置文件都是drbdadm来读取的,如:启动服务的时候,drbdadm会读取配置文件并把配置信息发给内核中的DRBD。
[root@node1 drbd]# 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"; [root@node1 drbd]#
主配置文件不用动,我们也看到了,它只是用include来整合别的配置文件的。当然如果你喜欢也可以把所有配置都放到这里来。
在/etc/drbd.d目录中的global_common.conf是定义全局和通用配置的,global段在整个配置中只能出现一次。而且如果多个配置或资源定义到这个文件中来,global段只能在配置文件中最上面。common段用来定义通用配置,只要是能在资源中定义的参数都可以在这里定义。
*.res是定义各种资源的配置文件,在drbd中所定义的存储叫做资源,可以定义多个资源,而在资源配置文件中没有定义到的,则以global_common.conf文件中的common项中的为准。
resource段是用来定义各种资源的。资源在定义时必须要为其命名,名字可以由非空白字符的ASCII字符组成,而且每一个resource段都要指定两个节点,一个本机,一个对端,以此来建立关联。
下面我们来看看global_common.conf文件中的内容和一般要做的配置。
global { usage-count no; #这个只是官方用来计数使用DRBD的数量的,我虚拟机网都上不去,yes也没用。 } common { protocol 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"; #在本地磁盘发生io错误以后,所做的操作。通告i/o错误,通告我要关机了,强制关机。 } disk { on-io-error detach; #drbd发生i/o错误以后,所做的动作,detach让资源离线。 } net { cram-hmac-alg "sha1"; #数据要以sha1加密传输 shared-secret "mypasswd"; #密码 } syncer { rate 1000M; #定义同步速率,这个很容易就把整个网络占满,所以在第一次同步完成后,可以改小点。 } }
没有做配置的部分,都没有贴上来。在我们配置文件中的handlers有的最好不要使用,会与高可用环境起冲突。上面没有贴出来的那些。
定义资源:这里假如我是为web服务所定义的资源。
[root@node1 drbd.d]# vim web.res resource web { #注定资源web on node1 { #指定node1节点的参数,node1是主机名称 device /dev/drbd0; #定义drbd设备,开启drbd服务以后会自动建立这个设备。 disk /dev/sdb1; #真实的磁盘,我这里所定义的是分区,工作环境中最好是磁盘。 address 192.168.1.11:7789; 监听的地址和端口。 meta-disk internal; #这个放到下面说吧。 } on node2 { device /dev/drbd0; disk /dev/sdb1; address 192.168.1.12:7789; meta-disk internal; } } ~
注意:两个节点的存储设备大小最好一样。如果主节点的存储比从节点的存储大,不知道为发生什么。
一开始未同步之前,磁盘是不用格式化的。要知道DRBD是块级别的同步,是在文件系统下面的。格式化也不过是在磁盘上写有关文件系统的信息。
上面的meta-disk有两种存储方式:internal和external。
internal表示DRBD的元数据信息与普通数据存在同一个底层存储上,存在存储设备的最后的位置。优点:容易管理,要坏一起坏,要好一起好。缺点磁盘开销大,而且如果磁盘原来有很多数据,建立DRBD的时候元数据可能会把原来的数据覆盖掉。(不管是哪种方式,都最好不要玩有数据的磁盘)。
external,是把元数据存在另一块磁盘上。优点性能好,缺点:如果元数据坏了,还要恢复元数据,如果数据坏了,还要修改元数据。
这位大哥写的里面参数挺详细的:http://lucifer119.blog.51cto.com/2914308/1262706
我们把这两个配置文件发到另一个节点上去:
[root@node1 drbd.d]# scp -r /etc/drbd.d/* node2:/etc/drbd.d/ global_common.conf 100% 629 0.6KB/s 00:00 web.res 100% 267 0.3KB/s 00:00 [root@node1 drbd.d]#
我这里已经在两个节点建立了/dev/sdb1的分区。我们启动服务试试。
如果提示没有加载drbd模块,就执行一下depmod试试。
启动服务
node1:
[root@node1 drbd.d]# service drbd start Starting DRBD resources: [ create res: web prepare disk: web adjust disk: web:failed(apply-al:255) adjust net: web ] .......... *************************************************************** DRBD's startup script waits for the peer node(s) to appear. - In case this node was already a degraded cluster before the reboot the timeout is 0 seconds. [degr-wfc-timeout] - If the peer was available before the reboot the timeout will expire after 0 seconds. [wfc-timeout] (These values are for resource 'web'; 0 sec -> wait forever) To abort waiting enter 'yes' [ 10]: #这些信息是表示在等待node2节点。 . [root@node1 drbd.d]#
node2:
[root@node2 drbd.d]# service drbd start Starting DRBD resources: [ create res: web prepare disk: web adjust disk: web:failed(apply-al:255) adjust net: web ] . [root@node2 drbd.d]#
OK,现在两个节点已经启动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:Diskless/Diskless 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:0 [root@node1 drbd.d]#
上面的Secondary,都处于从节点。后面的Diskless表示没有发现存储设备。状态信息可以看这里,而且drbd写得也很详细:http://www.linuxidc.com/Linux/2013-09/90321p3.htm
原因就是因为我们还没有创建drbd设备呢,我这里步骤给忘了,忘记了下面这一步。现在可以看下在/dev/下面有没有drbd0这个设备。
创建drbd设备:
node1: [root@node1 drbd.d]# drbdadm create-md web #web是配置文件中定义的资源。 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
node2: [root@node2 drbd.d]# drbdadm create-md web Writing meta data... initializing activity log NOT initializing bitmap New drbd meta data block successfully created. #创建成功 [root@node2 drbd.d]#
然后两个节点都重启drbd服务。然后查看下状态:
[root@node1 drbd.d]# 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:5253020 [root@node1 drbd.d]#
好啦,现在是处于不一致状态,因为我们还没有开始同步呢。现在只要指定一个节点为主节点,就会开始同步了。
哪个节点要成为主,就要在哪个节点上面执行。
[root@node1 drbd.d]# drbdadm primary --force web #强制为主节点。 [root@node1 drbd.d]# !cat 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:SyncSource ro:Primary/Secondary ds:UpToDate/Inconsistent C r---n- ns:294220 nr:0 dw:0 dr:299672 al:0 bm:17 lo:0 pe:3 ua:5 ap:0 ep:1 wo:f oos:4961180 [>...................] sync'ed: 5.7% (4844/5128)M finish: 0:00:50 speed: 97,280 (97,280) K/sec
好了,开始同步了,看到上面那个进度条了吧,知道我们为什么要用分区了吧,如果在整个磁盘,可要有一会儿了。
同步完成,查看状态:
[root@node1 drbd.d]# 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:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:5253020 nr:0 dw:0 dr:5253684 al:0 bm:321 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0
一致状态了,而且一现在这个节点为Primary了。现在就可以在主节点上格式化并挂载了。格式化只是在磁盘上写入信息,所以也是可以同步过去的。
在查看状态中,在表示主从节点那一项。 第一个表示本节点,第二个表示从节点。
如果在node2上查看状态,就变成。Secondary/Primary了。
注意:现在drbd0是双方的存储了。
[root@node1 drbd.d]# mke2fs -t ext4 /dev/drbd0
剩下的就简单了,挂载,写入文件。可以在另一个节点watch -n 1 'cat /proc/drbd实时查看状态。
[root@node1 drbd.d]# mount /dev/drbd0 /drbd
挂载了以后,可以写入一些文件,然后一会儿在另一个节点上查看是否存在。
下面我们看看怎么切换Primary和Secondary吧。
切换主节点
对于主从模型的drbd来说,同一时间只能有一个节点处于Primary,所以,如果想要切换主节点,就先要把主节点变成从节点。然后再把原来的从节点提升为Primary。
node1: 先把已经持载的drbd设备卸载。
[root@node1 ~]# umount /drbd [root@node1 ~]# drbdadm secondary web [root@node1 ~]# !cat 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:UpToDate/UpToDate C r----- ns:5469340 nr:0 dw:216320 dr:5254741 al:58 bm:321 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 [root@node1 ~]#
都是从节点了:
node2:
[root@node1 ~]# drbdadm secondary web [root@node2 drbd.d]# 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:Primary/Secondary ds:UpToDate/UpToDate C r----- ns:0 nr:5469340 dw:5469340 dr:664 al:0 bm:321 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0 [root@node2 drbd.d]# mkdir /drbd [root@node2 drbd.d]# mount /dev/drbd0 /drbd [root@node2 drbd.d]# ll /drbd total 20 drwx------ 2 root root 16384 Jul 4 18:36 lost+found drwxr-xr-x 10 root root 4096 Jul 4 18:41 rc.d [root@node2 drbd.d]#
我这里在node1节点上复制的rc.d目录,现在在node2上面挂载。
OK,总算是安装完成了。就写到这里吧。
如果有高可用集群的话,就可以实现节点自动转移了。这个就下次再说吧。
当务之急,开饭去。
这里因为我暂时也用不到drbd,所以也就没有过多的了解,大家有兴趣可以在这里http://down.51cto.com/data/324710
下载DRBD中文指南。是刘云峰2011年翻译的drbd英文文档。
对这些东西没什么经验,有些东西可能理解有误,所以如果朋友们有种“这是什么狗屁玩意”的感觉,请尽情的拍砖,这也是我的学习。谢谢大家