DRBD

Distributed Repliated Block Device 9

Posted by nomadli on September 2, 2020

特性

  • 内核IO底层, 对应用基本透明,在磁盘格式、分布式锁等下面,因此无法提供高层功能。
  • 单主模式 允许任意磁盘格式、可靠性高、支持故障转移。从节点磁盘不能挂载,即不能读写
  • 双主模式 允许在分布式磁盘系统上使用如GFS、OCFS2等。默认禁止,可能会出现问题。用于高可用分布式。
  • 复制协议A, 主节点写入磁盘并且将数据写入本地发送buf返回写入成功信号
  • 复制协议B, 主节点写入磁盘并且数据已经写入从节点接收buf,返回成功写入信号
  • 复制协议C, 主从节点都写入磁盘返回写入成功信号
  • 版本9以后支持多从接地,最多16节点
  • 版本9以后当启用auto promote选项使用drbdadm primary命令变主节点时,将自动装载卷并开始同步。
  • 支持TCP和RDMA两种传输模式,RDMA模式CPU不参与网络传输
  • 网络或机器故障恢复后,使用磁盘物理线性块同步,速度快、无需磁盘寻址。
  • 同步进行时采用了LVM的快照模式,主节点可以继续读写
  • 8.4版本后, 同步会检测网络情况自动调节同步速度、也可以配置固定速率同步
  • 可以开启基于hash算法的同步、减少相同块覆盖。
  • 复制可能会因为网络拥塞而暂停,情况好转后自动同步
  • 可以启用定时任务进行在线磁盘同步校验
  • 启用复制流hash校验,防止网络无法校验的位翻转. 网卡与主存间出现的位翻转
  • 人为或keeplive哨兵逻辑错误导致的多主数据不统一有四种情况自动恢复,或采用邮件通知手动恢复
  • 在支持磁盘刷新的设备上可以启用磁盘刷新,防止断电导致的磁盘缓存未写入。带UPS的磁盘可以关闭磁盘刷新
  • 8.4.3后自动支持固态硬盘或其它速写卡的Trim/Discard命令,可以瞬间删除或格式化磁盘
  • IO错误可以配置传递给上层或不传递,不传递将使用无盘模式,即只写入IO正常的节点。直到恢复
  • 当节点正在同步或复制过程中发生中断,磁盘被标记数据不一致,会禁止变为主节点。当过时节点可以变主
  • 三路复制已经弃用,即有两天链路可以选择不同的协议复制,也可以使用定时备份的模式
  • 可设置复制代理提供缓存,缓解网络压力,并提供块压缩功能
  • 采用浮动节点配置,可以使用IP而不是主机名作为节点标识
  • 对于大量数据可以采用离线同步,然后开启复制
  • 支持水平存储扩展,即块在多节点上冗余数据,而不是完全相同
  • 在实现冗余的基础上负载均衡读操作
  • 配置仲裁可以实现IO错误时自动切换,仲裁也可配置在一台非磁盘节点的服务器上
  • 9.0.25后支持centos8内核模块签名(Secure Boot / Kernel module signing)
  • vcs 这是商业实现

资源

  • 资源是一组复制集的集合,最多可以有65536个磁盘卷

网络

  • ipv4 ipv6
  • SuperSockets 使用RDMA模式,只有Dolphin Interconnect Solutions网卡支持,无CPU参与
  • InfiniBand HCAs、支持iWARP的NICs或支持RoCE的NICs网卡上实现RDMA传输,需少量CPU参与

脑裂自动恢复

  • 放弃较新主节点上的修改,最后变为主节点的修改被弃用
  • 放弃较旧主节点上的修改,最早变为主节点的修改被弃用
  • 放弃改动小的主节点上的修改
  • 只有一个节点有写入,直接恢复

安装

    yum install -y https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm
    yum install -y drbd90 kmod-drbd90
    https://github.com/LINBIT 源码安装
    iptables -I INPUT -p tcp --dport 7788:7799 -j ACCEPT
    iptables-save > /etc/sysconfig/iptables
    /etc/DRBD.conf 包含 /etc/drbd.d/global_common.conf /etc/drbd.d/*.res 所有节点相同
    vi /etc/drbd.d/global_common.conf
        global {
            usage-count no;
        }
        common {
            net {
                protocol C; //A B
                transport "tcp";//rdma
                allow-two-primaries no; //双主模式
                verify-alg sha1; //md5、crc32c 在线磁盘同步校验
                csums-alg sha1; //md5、crc32c 复制同步差异校验方法
                data-integrity-alg sha1; //md5、crc32c 复制数据传输正确性校验

                //拥塞策略
                on-congestion pull-ahead;
                congestion-fill 2G;
                congestion-extents 2000;

                //脑裂
                after-sb-0pri://裂脑被检测到,但此时资源在任何主机上都不是主要角色。
                disconnect;不要自动恢复,调用split brain处理程序脚本如果已配置,断开连接并以断开模式继续。
                discard-younger-primary;放弃并回滚对最后担任主服务器角色的主机所做的修改。
                discard-least-changes;丢弃并回滚发生较少更改的主机上的更改。
                discard-zero-changes;如果有任何主机根本没有发生任何更改,只需在另一个主机上应用所做的所有修改并继续。

                after-sb-1pri: 裂脑被检测到,此时资源在一个主机上扮演主要角色
                disconnect;与 after-sb-0pri 一样。
                consensus;应用 after-sb-0pri 中指定的相同恢复策略。如果在应用这些策略后可以选择裂脑受害者,则自动解决。否则,行为就像指定了 disconnect 一样。
                call-pri-lost-after-sb;应用 after-sb-0pri 中指定的恢复策略。如果在应用这些策略后可以选择裂脑受害者,请调用受害者节点上的 pri-lost-after-sb 处理程序。必须在 handlers 部分中配置此处理程序,并要求将节点从集群中强制删除。
                discard-secondary;无论哪个主机当前处于第二个角色,使该主机成为裂脑受害者

                after-sb-2pri:裂脑被检测到,此时资源在两个主机上都处于主要角色
                disconnect;与 after-sb-0pri 一样。

                //安装drbd-proxy和drbd-proxy.license后
                proxy {
		            memlimit 512M;
		            plugin {
			            zlib level 9;
		            }
	            }
            }
        }
    vi /etc/drbd.d/mydisk.res
        resource mydisk {
            net {
                protocol C; //A B
                transport "tcp";//rdma
            }

            disk {
                c-plan-ahead 5;     //5秒检测一次网络动态调整速率
                c-max-rate 10M;     //最大使用1M的带宽
                c-fill-target 2M;   //

                on-io-error detach; //发生IO错误丢弃备份设备以无盘模式运行
                on-io-error pass_on; //IO发生在主节点报告错误,次节点忽略
                on-io-error call-local-io-error;//调用自定义IO错误处理程序

                //如果只有部分主机有缓存可以把disk移动到on hostname节点里面
                disk-flushes yes;  //启用复制数据的强制磁盘刷新
                md-flushes yes;    //元数据的强制磁盘刷新

            }
            disk {
                c-plan-ahead 0;     //固定速率
                cresync-rate 10M;   //10M带宽
            }

            handlers {  // 可以使用任何系统命令
                split-brain "/usr/lib/drbd/notify-split-brain.sh root";//数据脑裂逻辑, 将邮件通知root
            }
            

            volume 0 {
                device    /dev/drbd1;
                disk      /dev/sda7;
                meta-disk internal;
            }
            volume 1 {
                device    /dev/drbd2;
                disk      /dev/sda8;
                meta-disk internal;
            }

            //链接数是 n*(n-1)/2

            //单网卡
            on hostname-1 {
                address   10.1.1.31:7789;
                node-id   0;
                proxy on ostname-1 {
			        inside 127.0.0.1:7815; 节点与代理通信
			        outside 192.168.23.1:7715; 代理间通信
		        }
            }
            on hostname-2 {
                address   10.1.1.32:7789;
                node-id   1;
            }
            on hostname-3 {
                address   10.1.1.33:7789;
                node-id   2;
            }
            connection-mesh {
                hosts hostname-1 hostname-2 hostname-3;
            }

            //多网卡
            connection {
                host hostname-1     address 10.1.2.1:7010;
                host hostname-2     address 10.1.2.2:7001;
            }
            connection {
              host hostname-1       address 10.1.3.1:7020;
              host hostname-3       address 10.1.3.2:7002;
            }
            connection {
                host hostname-2     address 10.1.4.1:7021;
                host hostname-3     address 10.1.4.2:7012;
            }
        }

    drbdadm create-md --max-peers=xx mydisk         //初始化元数据
    提示 drbdmeta 1 v09 /dev/xxx internal create-md x terminated with exit code 40 磁盘空不能判断大小
    dd if=/dev/zero of=/dev/xxx bs=1M count=100 写入100M数据

    drbdadm up mydisk                               //启用资源
    drbdadm status mydisk                           //查看资源状态

    drbdadm primary --force mydisk  //同步原始数据,在一台要保留数据的节点上执行,其它节点数据丢失
    drbdadm status mydisk                           //查看资源同步状态
    drbdadm status mydisk --verbose --statistics

    mkfs.ext4 /dev/drbdx
    mount /dev/drbdx /xxx


    //或离线同步
    //保留数据的机器上执行
    drbdadm new-current-uuid --clear-bitmap mydisk/volume 0
    drbdadm new-current-uuid --clear-bitmap mydisk/volume 1
    使用RAD-1或按位复制(dd命令)到临时挂载的备份机的磁盘上
    drbdadm new-current-uuid mydisk


    //在备份机上执行
    将磁盘插入备份机,在磁盘未使用情况下,执行命令将节点ID修改
    drbdadm -- --force [--stacked 堆栈需要] dump-md mydisk/volume0 > /tmp/md_orig.txt
    
    sed -e "s/node-id 1/node-id 0/" \
	-e "s/^peer.1. /peer-NEW /" \
	-e "s/^peer.0. /peer[1] /" \
	-e "s/^peer-NEW /peer[0] /" \
	< /tmp/md_orig.txt > /tmp/md.txt

    drbdmeta --force [--stacked 堆栈需要] $(drbdadm sh-minor mydisk/volume0) v09 $(drbdadm sh-ll-dev mydisk/volume0) inter

    mydisk/volume1 也是相同的操作

    drbdadm up mydisk       //启用资源
    节点连接建立后,只会同步及复制后期变化的数据

    drbdsetup events2 --now –statistics –timestamp mydisk 更底层的监控
    drbdadm cstate mydisk 链接状态
    drbdadm cstate hostname-1:mydisk 只看单个节点的链接状态

    drbdadm role mydisk 查看节点角色
    drbdadm dstate mydisk 磁盘状态

    drbdadm down mydisk 禁用资源

    故障切换
    主节点
    umount /dev/drbd/by-res/mydisk/volume0
    drbdadm secondary mydisk 将节点降为从节点

    从节点
    drbdadm primary mydisk 将节点提升为主节点
    mount /dev/drbd/by-res/mydisk/volume0 <mountpoint>

    
    升级
    systemctl stop drbd
    yum upgrade
    rmmod drbd 卸载旧内核,如果出现错误应该是有些资源没有停止 drbdadm down all
    modprobe drbd 加载新内核
    drbdadm dump all 可以将旧的配置导出为新版的配置 大版本变动
    drbdadm create-md --max peers=xx mydisk 更改元数据 大版本变动需要
    drbdadm up mydisk 启动同步
    systemctl start drbd

    drbdadm net-options --protocol=C --allow-two-primaries mydisk 临时允许双主
    drbdadm net-options --protocol=C --allow-two-primaries=no mydisk 停止

    drbdadm verify mydisk 联机验证磁盘
    如果校验不同步,调用下面命令重新同步
    drbdadm disconnect mydisk
    drbdadm connect mydisk

    修改配置->同步所有节点配置->drbdadm adjust mydisk

    drbdadm resize mydisk 在线扩容,次扩容的是逻辑卷如LVM,此时只能有一个主
    drbdadm -- --assume-clean resize mydisk 扩容磁盘数据为空跳过同步
    drbdadm resize --size=xxK|M|G mydisk 在线缩容

    如果扩容非逻辑块设备, 且使用external meta data
    drbdadm down mydisk
    添加磁盘
    drbdadm up mydisk

    如果扩容非逻辑块设备, 且使用internal meta data
    drbdadm down mydisk
    drbdadm dump-md mydisk > /tmp/metadata 每个节点
    添加磁盘
    编辑/tmp/metadata 在扇区中修改la-size-sect
    drbdadm create-md mydisk
    drbdmeta_cmd=$(drbdadm -d dump-md mydisk)
    ${drbdmeta_cmd/dump-md/restore-md} /tmp/metadata
    drbdadm up mydisk
    drbdadm primary mydisk

    离线缩容块设备都与internal meta data类似,只是external meta data无需导入导出

    drbdadm dstate all 将显示所有资源, all 可以用在所有资源名的地方

    drbd-proxy-ctl -c 代理配置

节点角色 drbdadm role all

  • Primary 主角色中,可以读取和写入。此角色仅在两个节点中的一个节点上发生,除非启用了dual-primary mode
  • Secondary 资源当前处于辅助角色中。它通常从其对等方接收更新(除非在断开连接模式下运行),但既不能读取也不能写入
  • Unknown 对等方的资源角色显示,并且仅在断开连接模式下显示。

网络状态 drbdadm cstate all

  • StandAlone 没有可用的网络配置。资源尚未连接,或者已被管理性断开(使用 drbdadm disconnect),或者由于身份验证失败或脑裂而断开其连接。
  • Disconnecting 断开连接期间的临时状态。下一个状态是 StandAlone。
  • Unconnected 临时状态,在尝试连接之前。可能的下一个状态: Connecting。
  • Timeout 与对等方通信超时后的临时状态。下一个状态:Unconnected。
  • BrokenPipe 与对等方的连接丢失后的临时状态。下一个状态: Unconnected 。
  • NetworkFailure 与伙伴的连接丢失后的临时状态。下一个状态: Unconnected。
  • ProtocolError 与伙伴的连接丢失后的临时状态。下一个状态:Unconnected。
  • TearDown 临时状态。对等方正在关闭连接。下一个状态: Unconnected。
  • Connecting 此节点正在等待,直到对等节点在网络上变为可见
  • Connected 已建立DRBD连接,数据镜像现在处于活动状态。这是正常状态。

复制状态

  • Off 由于连接未连接,因此卷未通过此连接进行复制。
  • Established 对该卷的所有写入都将在线复制。这是正常状态。
  • StartingSyncS 由管理员启动的完全同步正在启动。下一个可能是:SyncSource 或 PausedSyncS
  • StartingSyncT 由管理员启动的完全同步正在启动。下一个状态:WFSyncUUID。
  • WFBitMapS 部分同步刚刚开始。下一个可能的状态:SyncSource_或_PausedSyncS。
  • WFBitMapT 部分同步刚刚开始。下一个可能的状态:WFSyncUUID。
  • WFSyncUUID 同步即将开始。下一个可能的状态:SyncTarget_或_PausedSyncT。
  • SyncSource 同步当前正在运行,本地节点是同步源。
  • SyncTarget 同步当前正在运行,本地节点是同步的目标。
  • PausedSyncS 本地节点是正在进行的同步的源,但同步当前已暂停。这可能是由于依赖于另一个同步进程的完成,或者是由于同步已被 drbdadm pause sync 手动中断。
  • PausedSyncT 本地节点是正在进行的同步的目标,但同步当前已暂停。这可能是由于依赖于另一个同步进程的完成,或者是由于同步已被 drbdadm pause sync 手动中断。
  • VerifyS 联机设备验证当前正在运行,本地节点是验证源。
  • VerifyT 联机设备验证当前正在运行,本地节点是验证的目标。
  • Ahead Data replication was suspended, since the link can not cope with the load. This state is enabled by the configuration on-congestion option
  • Behind 数据复制被对等方挂起,因为链接无法处理负载。此状态由对等节点上的配置 on-congestion 选项启用

磁盘状态 drbdadm dstate all

  • Diskless 没有为DRBD驱动程序分配本地块设备。这可能意味着资源从未连接到其备份设备,它已使用 drbdadm detach 手动分离,或者在发生较低级别的I/O错误后自动分离。
  • Attaching 读取元数据时的临时状态。
  • Detaching 在分离并等待正在进行的IOs完成时的临时状态。
  • Failed 本地块设备报告I/O失败后的瞬态。下一个状态:Diskless。
  • Negotiating 在 已经Connected 的DRBD设备上执行附加操作时的瞬态。
  • Inconsistent 数据不一致。在两个节点上(在初始完全同步之前)创建新资源时立即出现此状态。此外,在同步期间,在一个节点(同步目标)中可以找到此状态。
  • Outdated 资源数据一致,但outdated。
  • DUnknown 如果没有可用的网络连接,则此状态用于对等磁盘。
  • Consistent 没有连接的节点的一致数据。建立连接后,决定数据是 UpToDate 还是 Outdated。
  • UpToDate 数据的一致、最新状态。这是正常状态。

用户态工具 DRBD-utils

  • drbdadm 从/etc/DRBD.conf读取配置,作为drbdsetup drbdmeta的前端工具
  • drbdadm -d 选项可以模拟命令执行,查看哪些drbdsetup drbdmeta命令被调用
  • drbdsetup 将配置加载到内核,用户一般无需直接调用该命令
  • drbdmeta 创建、转储、还原和修改DRBD元数据结构,用户一般无需手动调用
  • drbdmon 监控工具
  • drbdtop 交互监控

状态含义

  • local 显示网络协议栈、用于接受来自对等方的连接的本地地址和端口。
  • peer 显示网络协议栈、对等方节点地址和用于连接的端口。
  • congested 此标志指示数据连接的TCP发送缓冲区是否已填充80%以上。
  • send (network send) 通过网络连接发送给伙伴的网络数据量;单位为千字节。
  • receive (network receive) 伙伴通过网络连接接收的网络数据量;单位为千字节。
  • read (disk write) 写在本地硬盘上的网络数据;以千字节为单位。
  • written (disk read) 从本地硬盘读取的网络数据;单位为千字节。
  • al-writes (activity log) 元数据活动日志区域的更新次数。
  • bm-writes (bit map) 元数据位图区域的更新次数。
  • lower-pending (local count) DRBD向本地I/O子系统发出的打开请求数。
  • pending 发送给合作伙伴但尚未由后者应答的请求数。
  • unacked (unacknowledged) 伙伴通过网络连接接收但尚未应答的请求数。
  • upper-pending (application pending) 转发给DRBD但尚未由DRBD应答的块I/O请求数。
  • write-ordering (write order) 当前使用的写排序方法b(barrier), f(flush), d(drain) 或者 n(none).
  • out-of-sync 当前不同步的存储量;单位为千字节。
  • resync-suspended 重新同步是否当前挂起。可能的值是: no, user, peer, dependency.
  • blocked 显示本地I/O拥塞

修复

  • 有节点正常,Outdated节点 drbdadm disconnect sname && drbdadm connect sname
  • 节点看不到其它节点, drbdadm down sname && drbdadm up sname
  • StandAlone如果主节点正则 drbdadm disconnect sname && drbdadm connect –discard-my-data sname, 主节点下这台也是StandAlone,则主节点disconn && connect
  • Inconsistent drbdadm invalidate sname && drbdadm down sname && drbdadm create-md sname && drbdadm adjust sname && drbdadm up sname
  • 所有节点数据异常 选最后一台主机 drbdadm del-peer sname && drbdadm –force sname