负载均衡高可用

DRBD笔记:Linux平台下实现高可用方案[转]

网上看到了这篇文章,对于drbd概念的理解还是很有帮助的。

DRBD实际上是一种块设备的实现,主要被用于Linux平台下的高可用(HA)方案之中。他是有内核模块和相关程序而组成,通过网络通信来同步镜像整个设备,有点类似于一个网络RAID的功能。也就是说当你将数据写入本地的DRBD设备上的文件系统时,数据会同时被发送到网络中的另外一台主机之上,并以完全相同的形式记录在一个文件系统中(实际上文件系统的创建也是由DRBD的同步来实现的)。本地节点(主机)与远程节点(主机)的数据可以保证实时的同步,并保证IO的一致性。所以当本地节点的主机出现故障时,远程节点的主机上还会保留有一份完全相同的数据,可以继续使用,以达到高可用的目的。

    在高可用(HA)解决方案中使用DRBD的功能,可以代替使用一个共享盘阵存储设备。因为数据同时存在于本地主机和远程主机上,在遇到需要切换的时候,远程主机只需要使用它上面的那份备份数据,就可以继续提供服务了。

底层设备支持

    DRBD需要构建在底层设备之上,然后构建出一个块设备出来。对于用户来说,一个DRBD设备,就像是一块物理的磁盘,可以在商脉内创建文件系统。DRBD所支持的底层设备有以下这些类:

    1、一个磁盘,或者是磁盘的某一个分区;

    2、一个soft raid 设备;

    3、一个LVM的逻辑卷;

    4、一个EVMS(Enterprise Volume Management System,企业卷管理系统)的卷;

    5、其他任何的块设备。

    配置简介

    1、全局配置项(global)

        基本上我们可以做的也就是配置usage-count是yes还是no了,usage-count参数其实只是为了让linbit公司收集目前drbd的使用情况。当drbd在安装和升级的时候会通过http协议发送信息到linbit公司的服务器上面。

    2、公共配置项(common)

        这里的common,指的是drbd所管理的多个资源之间的common。配置项里面主要是配置drbd的所有resource可以设置为相同的参数项,比如protocol,syncer等等。

    3、资源配置项(resource)

        resource项中配置的是drbd所管理的所有资源,包括节点的ip信息,底层存储设备名称,设备大小,meta信息存放方式,drbd对外提供的设备名等等。每一个resource中都需要配置在每一个节点的信息,而不是单独本节点的信息。实际上,在drbd的整个集群中,每一个节点上面的 drbd.conf文件需要是完全一致的。

        另外,resource还有很多其他的内部配置项:

        net:网络配置相关的内容,可以设置是否允许双主节点(allow-two-primaries)等。

        startup:启动时候的相关设置,比如设置启动后谁作为primary(或者两者都是primary:become-primary-on both)

        syncer:同步相关的设置。可以设置“重新”同步(re-synchronization)速度(rate)设置,也可以设置是否在线校验节点之间的数据一致性(verify-alg 检测算法有md5,sha1以及crc32等)。数据校验可能是一个比较重要的事情,在打开在线校验功能后,我们可以通过相关命令(drbdadm verify resource_name)来启动在线校验。在校验过程中,drbd会记录下节点之间不一致的block,但是不会阻塞任何行为,即使是在该不一致的 block上面的io请求。当不一致的block发生后,drbd就需要有re-synchronization动作,而syncer里面设置的rate 项,主要就是用于re-synchronization的时候,因为如果有大量不一致的数据的时候,我们不可能将所有带宽都分配给drbd做re- synchronization,这样会影响对外提提供服务。rate的设置和还需要考虑IO能力的影响。如果我们会有一个千兆网络出口,但是我们的磁盘 IO能力每秒只有50M,那么实际的处理能力就只有50M,一般来说,设置网络IO能力和磁盘IO能力中最小者的30%的带宽给re- synchronization是比较合适的(官方说明)。另外,drbd还提供了一个临时的rate更改命令,可以临时性的更改syncer的rate 值:drbdsetup /dev/drbd0 syncer -r 100M。这样就临时的设置了re-synchronization的速度为100M。不过在re-synchronization结束之后,你需要通过 drbdadm adjust resource_name 来让drbd按照配置中的rate来工作。

资源管理

    1、增加resource的大小:

    当遇到我们的drbd resource设备容量不够的时候,而且我们的底层设备支持在线增大容量的时候(比如使用lvm的情况下),我们可以先增大底层设备的大小,然后再通过 drbdadm resize resource_name来实现对resource的扩容。但是这里有一点需要注意的就是只有在单primary模式下可以这样做,而且需要先在所有节点上都增大底层设备的容量。然后仅在primary节点上执行resize命令。在执行了resize命令后,将触发一次当前primary节点到其他所有secondary节点的re-synchronization。

    如果我们在drbd非工作状态下对底层设备进行了扩容,然后再启动drbd,将不需要执行resize命令(当然前提是在配置文件中没有对disk参数项指定大小),drbd自己会知道已经增大了容量。

    在进行底层设备的增容操作的时候千万不要修改到原设备上面的数据,尤其是drbd的meta信息,否则有可能毁掉所有数据。

    2、收缩resource容量:

    容量收缩比扩容操作要危险得多,因为该操作更容易造成数据丢失。在收缩resource的容量之前,必须先收缩drbd设备之上的容量,也就是文件系统的大小。如果上层文件系统不支持收缩,那么resource也没办法收缩容量。

    如果在配置drbd的时候将meta信息配置成internal的,那么在进行容量收缩的时候,千万别只计算自身数据所需要的空间大小,还要将drbd的meta信息所需要的空间大小加上。

    当文件系统收缩好以后,就可以在线通过以下命令来重设resource的大小:drbdadm — –size=***G resize resource_name。在收缩的resource的大小之后,你就可以自行收缩释放底层设备空间(如果支持的话)。

    如果打算停机状态下收缩容量,可以通过以下步骤进行:

        a、在线收缩文件系统

        b、停用drbd的resource:drbdadm down resourcec_name

        c、导出drbd的metadata信息(在所有节点都需要进行):drbdadm dump-md resource_name > /path_you_want_to_save/file_name

        d、在所有节点收缩底层设备

        e、更改上面dump出来的meta信息的la-size-sect项到收缩后的大小(是换算成sector的数量后的数值)

   f、如果使用的是internal来配置meta-data信息,则需要重新创建meta-data:drbdadm create-md resource_name

   g、将之前导出并修改好的meta信息重新导入drbd(摘录自linbit官方网站的一段导入代码):

    drbdmeta_cmd=$(drbdadm -d dump-md test-disk)

            ${drbdmeta_cmd/dump-md/restore-md} /path_you_want_to_save/file_name
        h、启动resource:drbdadm up resource_name

磁盘损坏

    1、detach resource

        如果在resource的disk配置项中配置了on_io_error为pass_on的话,那么drbd在遇到磁盘损坏后不会自己detach底层设备。也就是说需要我们手动执行detach的命令(drbdadm detach resource_name),然后再查看当前各节点的ds信息。可以通过cat /proc/drbd来查看,也可以通过专有命令来查看:drbdadm dstat resource_name。当发现损坏的那方已经是Diskless后,即可。如果我们没有配置on_io_error或者配置成detach的话,那么上面的操作将会由自动进行。

        另外,如果磁盘损坏的节点是当前主节点,那么我们需要进行节点切换的操作后再进行上面的操作。

    2、更换磁盘

        当detach了resource之后,就是更换磁盘了。如果我们使用的是internal的meta-data,那么在换好磁盘后,只需要重新创建 mata-data(drbdadm create-md resource_name),再将resource attach上(drbdadm attach resource_name),然后drbd就会马上开始从当前primary节点到本节点的re-synchronisation。数据同步的实时状况可以通过 /proc/drbd文件的内容获得。

        不过,如果我们使用的不是internal的meta-data保存方式,也就是说我们的meta-data是保存在resource之外的地方的。那么我们在完成上面的操作(重建meta-data)之后,还需要进行一项操作来触发re-synchnorisation,所需命令为:drbdadm invalidate resource_name 。

   节点crash(或计划内维护)

    1、secondary节点

        如果是secondary接待你crash,那么primary将临时性的与secondary断开连接,cs状态应该会变成WFConnection,也就是等待连接的状态。这时候primary会继续对外提供服务,并在meta-data里面记录下从失去secondary连接后所有变化过的 block的信息。当secondary重新启动并连接上primary后,primary –> secondary的re-synchnorisation会自动开始。不过在re-synchnorisation过程中,primary和 secondary的数据是不一致状态的。也就是说,如果这个时候primary节点也crash了的话,secondary是没办法切换成 primary的。也就是说,如果没有其他备份的话,将丢失所有数据。

    2、primary节点

        一般情况下,primary的crash和secondary的crash所带来的影响对drbd来说基本上是差不多的。唯一的区别就是需要多操作一步将 secondary节点switch成primary节点先对外提供服务。这个switch的过程drbd自己是不会完成的,需要我们人为干预进行一些操作才能完成。当crash的原primary节点修复并重新启动连接到现在的primary后,会以secondary存在,并开始re- synchnorisation这段时间变化的数据。

        在primary节点crash的情况下,drbd可以保证同步到原secondary的数据的一致性,这样就避免了当primary节点crash之后,secondary因为数据的不一致性而无法wcitch成primary或者即使切换成primary后因为不一致的数据无法提供正常的服务的问题。

    3、节点永久性损坏(需要更换机器或重新安装相关软件的情况)

        当某一个节点因为硬件(或软件)的问题,导致某一节点已经无法再轻易修复并提供服务,也就是说我们所面对的是需要更换主机(或从OS层开始重新安装)的问题。在遇到这样的问题后,我们所需要做的是重新提供一台和原节点差不多的机器,重新开始安装os,安装相关软件,从现有整提供服务的节点上copy出 drbd的配置文件(/etc/drbd.conf),创建meta-data信息,然后启动drbd服务,以一个secondary的身份连接到现有的 primary上面,后面就会自动开始re-synchnorisation。

    split brain的处理

    split brain实际上是指在某种情况下,造成drbd的两个节点断开了连接,都以primary的身份来运行。当drbd某primary节点连接对方节点准备发送信息的时候如果发现对方也是primary状态,那么会会立刻自行断开连接,并认定当前已经发生split brain了,这时候他会在系统日志中记录以下信息:“Split-Brain detected,dropping connection!”当发生split brain之后,如果查看连接状态,其中至少会有一个是StandAlone状态,另外一个可能也是StandAlone(如果是同时发现split brain状态),也有可能是WFConnection的状态。

    如果我们在配置文件中配置了自动解决split brain(好像linbit不推荐这样做),drbd会自行解决split brain问题,具体解决策略是根据配置中的设置来进行的。

    如果没有配置split brain自动解决方案,我们可以手动解决。首先我们必须要确定哪一边应该作为解决问题后的primary,一旦确定好这一点,那么我们同时也就确定接受丢失在split brain之后另外一个节点上面所做的所有数据变更了。当这些确定下来后,我们就可以通过以下操作来恢复了:

    a、首先在确定要作为secondary的节点上面切换成secondary并放弃该资源的数据:

        drbdadm secondary resource_name

        drbdadm — –discard-my-data connect resource_name

    b、在要作为primary的节点重新连接secondary(如果这个节点当前的连接状态为WFConnection的话,可以省略)

        drbdadm connect resource_name

    当作完这些动作之后,从新的primary到secondary的re-synchnorisation会自动开始。

meta data存放地点的比较

    1、internal meta-data(meta-data和数据存放在同一个底层设备之上)

    优点:一旦meta-data创建之后,就和实际数据绑在了一起,在维护上会更简单方便,不用担心meta-data会因为某些操作而丢失。另外在硬盘损坏丢失数据的同时,meta-data也跟着一起丢失,当更换硬盘之后,只需要执行重建meta-data的命令即可,丢失的数据会很容易的从其他节点同步过来。

    缺点:如果底层设备是单一的磁盘,没有做raid,也不是lvm等,那么可能会造成性能影响。因为每一次写io都需要更新meta-data里面的信息,那么每次写io都会有两次,而且肯定会有磁头的较大寻道移动,因为meta-data都是记录在dice设备的最末端的,这样就会造成写io的性能降低。

    2、external meta data(meta-data存放在独立的,与存放数据的设备分开的设备之上)

    优点:与internal meta-data的缺点完全相对,可以解决写io的争用问题。

    缺点:由于meta-data存放在与数据设备分开的地方,就意味着当磁盘损坏更换磁盘之后,必须手动发起全量同步的操作。也就是管理维护会稍微麻烦那么一点点,很小的一点点。

    如果我们希望在已经存在数据的设备上面建立drbd的资源,并且不希望丢失该设备上面的数据,又没办法增大底层设备的容量,而且上层文件系统又没办法收缩的话,我们就只能将meta data创建成external方式。

Related Post

4 Comments

  1. 理论上来说是可以这样做的,但需要关注几个问题,mysql的使用偏重是读还是写,如果采用共享,使用什么方式是nfs还是什么,还有就是网络i/o是否满足性能要求。

  2. 在高可用(HA)解决方案中使用DRBD的功能,可以代替使用一个共享盘阵存储设备
    —–hi,蚊子,请教下,DRBD的方案中mysql的数据可以放在同一个共享阵列的文件系统上吗?

  3. 蚊子,有在 mysql replication环境下,master出现问题,slave自动替换角色成为master的案例吗?

    slave可以手工或者自动的!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.