You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DRBD双节点主备集群脑裂自动恢复配置优化咨询

DRBD双节点主备集群脑裂自动恢复配置优化咨询

兄弟,太懂你这种需求了——就想让这个双节点DRBD集群不管碰到啥脑裂情况,只要不是俩机器全挂,就得有个节点能立刻顶上去提供服务,数据丢点无所谓,服务不能断对吧?结合你现在碰到的StandAlone、force-io-failures卡壳问题,咱从DRBD配置、脚本优化、兜底措施这几块来调整,彻底解决这些痛点。

一、核心DRBD资源配置调整(直接抄改你的配置文件)

首先把你的DRBD资源配置(一般在/etc/drbd.d/xxx.res)改成下面这样,每一项都贴合你“可用性优先”的需求:

resource your_resource {
    protocol C;  # 用同步协议保证基本一致性,你要是更激进也可以用A,但C足够满足需求
    meta-disk internal;
    device /dev/drbd0;  # 换成你的DRBD设备号

    on node1 {  # 这里把node1设为优先主节点,你可以换成自己的节点名
        disk /dev/sdb1;  # 你的底层磁盘路径
        address 192.168.1.10:7789;  # 节点IP+DRBD监听端口
        node-id 0;
    }

    on node2 {
        disk /dev/sdb1;
        address 192.168.1.11:7789;
        node-id 1;
    }

    net {
        split-brain-detection resource-only;  # 只检测资源级脑裂,响应更快
        ping-interval 1;          # 每秒发一次检测包
        ping-timeout 5;           # 5秒没回应就判定节点失联
        ping-count 3;             # 连续3次超时触发脑裂处理逻辑
        on-suspended-primary-outdated force-secondary;  # 失联后回来的旧primary直接切为secondary
        on-suspended-secondary-outdated resume-primary; # 旧secondary在primary失联时直接恢复成primary
    }

    handlers {
        after-sb-0pri "drbdadm force-primary your_resource node1";  # 脑裂后俩节点都是secondary,直接让node1抢primary
        after-sb-1pri "drbdadm discard-secondary your_resource";    # 脑裂后有一个primary,直接丢弃secondary的数据同步
        after-sb-2pri "drbdadm force-primary your_resource node1";  # 脑裂后俩节点都自认为primary,强制node1赢,node2认怂
        pri-lost-after-sb "drbdadm clear-force-io-failures your_resource; drbdadm secondary your_resource";  # 不用重启!直接清理故障状态切secondary
    }
}

为啥这么改?

  • 把pri-lost-after-sb从reboot改成直接清理故障状态,避免节点重启导致的服务中断;
  • 所有脑裂场景都直接指定优先节点(node1)成为primary,彻底杜绝“俩节点都卡着不动”的情况;
  • 缩短脑裂检测的超时时间,尽早触发恢复逻辑,减少服务不可用窗口;
  • 处理on-suspended-secondary-outdated的情况,确保旧secondary在primary真挂了的时候能立刻顶上去,不会卡在不可用状态。

二、挂载脚本优化(解决force-io-failures导致的挂载失败)

你原来的挂载脚本只检测primary状态,但碰到force-io-failures标记时,磁盘是没法挂载的,所以给脚本加个清理步骤:

#!/bin/bash
RESOURCE="your_resource"
MOUNT_POINT="/mnt/drbd_data"

# 获取当前节点的DRBD角色
ROLE=$(drbdadm role $RESOURCE)

if [[ $ROLE == *"Primary"* ]]; then
    # 先清理force-io-failures标记,不然挂载会失败
    drbdadm clear-force-io-failures $RESOURCE
    # 检查是否已经挂载,没挂载就执行挂载
    if ! mountpoint -q $MOUNT_POINT; then
        mount /dev/drbd0 $MOUNT_POINT
    fi
else
    # 如果是secondary,确保挂载点已经卸载,避免脑裂后双写风险
    if mountpoint -q $MOUNT_POINT; then
        umount $MOUNT_POINT
    fi
fi

然后把这个脚本和DRBD的状态变化绑定——可以用DRBD的notify-handler,或者在systemd的DRBD服务里加ExecStartPost/ExecReloadPost触发脚本,确保状态一变就自动执行。

三、兜底措施(防止节点卡在StandAlone状态)

有时候网络闪断可能导致节点进入StandAlone状态,这时候可以加个定时任务(用cron)定期检查状态,自动修复:

#!/bin/bash
RESOURCE="your_resource"
ROLE=$(drbdadm role $RESOURCE)

if [[ $ROLE == "StandAlone" ]]; then
    # 先尝试重新连接资源
    drbdadm connect $RESOURCE
    # 如果是优先节点(node1),强制切为primary
    if [[ $(hostname) == "node1" ]]; then
        drbdadm primary $RESOURCE
    fi
fi

给这个脚本加个每分钟执行的cron任务:

* * * * * root /path/to/your/standalone_fix.sh >> /var/log/drbd_standalone_fix.log 2>&1

四、测试验证(一定要测!)

改完配置后,一定要模拟几个场景验证:

  1. 断开俩节点的网络,模拟脑裂,然后恢复网络,看是否自动回到主备状态;
  2. 把primary节点关机,看secondary是否自动切为primary并挂载磁盘;
  3. 把primary节点开机,看是否自动切为secondary并同步数据;
  4. 模拟俩节点都自认为primary的情况(比如手动在俩节点都执行drbdadm primary),恢复网络后看是否自动让node1成为primary。

备注:内容来源于stack exchange,提问作者eagr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.21 14:59:32