关于我们

质量为本、客户为根、勇于拼搏、务实创新

< 返回新闻公共列表

2026 服务器租用做双机热备吃什么资源?DRBD 块级复制协议与脑裂恢复实测 + 避坑全解

发布时间:2026-09-29

2026 服务器租用做双机热备吃什么资源?DRBD 块级复制协议与脑裂恢复实测 + 避坑全解

开篇:它把你的磁盘实时抄一份,代价写在每一次 fsync 里

双机热备这事儿,很多人第一反应是"搞个主从同步不就行了"。真上手才发现,主从是数据库层面的概念,DRBD 根本不认识什么叫表、什么叫事务——它蹲在文件系统下面,眼里只有块。你上层跑 MySQL 也好、跑 PostgreSQL 也好,哪怕只是个普通目录挂在那儿,DRBD 都照单全收,把每一次块写实时抄一份发给对端。听起来省心,代价全藏在两个地方:一个是每一次 fsync 的延迟里,另一个是某天凌晨三点你被电话叫起来处理脑裂。

这篇文章只聊一件事:DRBD 到底吃服务器哪几样资源,以及脑裂怎么防、怎么判、怎么恢复。别的地方讲高可用喜欢把一堆方案铺开对比,我不这么写——铺开讲没用,你真要落地,卡住你的永远是下面这几个具体问题。

  • 它主要吃三样东西:磁盘顺序写、网络带宽、元数据盘的随机 IO。CPU 和内存基本不是瓶颈,别把预算花错地方。
  • Protocol C 下写延迟 = 本地写 + 网络往返 + 对端写,跨机房等于把 RTT 直接加进每一次 fsync。
  • 真正让运维半夜起床的不是复制,是脑裂——两端都认为自己是主,各写各的,恢复时你必须人工决定丢弃哪一份数据。
  • DRBD 自己不解决"谁该活",隔离(fencing)得靠 Pacemaker/Corosync 的 STONITH 或者硬件 fence。
  • 它只做数据镜像,不做服务切换,VIP 漂移、应用拉起、资源代理这些还得另外配一套。

DRBD 工作在块层:镜像的是块,不是文件

块层意味着"上层完全看不见它"

DRBD 的位置在块设备层,也就是在文件系统之下。文件系统把你的写操作翻译成对某些块的写入请求,DRBD 在下面接住这个请求:一边写本地磁盘,一边通过网络把同样的数据发给对端。对上层来说,它看到的还是一个普通的块设备,文件系统该怎么跑还怎么跑,应用程序一行代码都不用改。

这就是块级复制最大的好处——不挑应用。数据库自带的主从复制要求你用固定的数据库、固定的版本、还得处理 binlog 格式、并行回放、GTID 那一堆事;DRBD 不管这些,你上面是 InnoDB 也好、是 MongoDB 也好、是某个自己写的二进制存储引擎也好,它一视同仁。反过来说,代价也很直接:它不理解文件语义。你删一个 1KB 的小文件,在它眼里就是若干个块的写入;你做一次大文件顺序写,它就是实打实地把这么多块全发出去。没有"只同步变化的那一行"这种好事。

代价:两端块大小与顺序必须一致

因为镜像的是块,两端的块大小、偏移量、写顺序必须严格一致。这带来几条硬约束:两端磁盘容量必须一致(小的一端会把大的一端也限制住);两端最好同型号同规格,否则性能被慢的那一端拖住——你的本地盘是 NVMe、对端是机械盘,那你在 Protocol C 下每一次写都在等对端的机械盘,写入延迟直接对齐到最慢的那个。

写顺序这块,DRBD 用 barriers 来保证有依赖关系的写按顺序落地。在支持 barrier 的 IO 栈上(现在的主流内核和文件系统基本都支持),这套机制是生效的,能保证一致性;某些配置下可以关掉 barrier 换取一点性能,但那是拿一致性换的,别为了几个百分点的吞吐去动它。说白了,barrier 开着的时候你觉得慢,关了之后出问题你会觉得更慢。

角色:Primary 与 Secondary,同一时刻只能有一个主

DRBD 的节点角色分 Primary 和 Secondary。Primary 可以挂载、可以读写;Secondary 不能挂载,只负责接收数据。单主模式下,同一时刻只允许一端是 Primary。这一点很多人第一次上手会懵:备机上明明有完整的数据,为什么不让看?因为块设备在被复制的过程中,Secondary 端的文件系统状态是不被允许直接访问的,你要看只能先切换角色。

想两端同时读写(dual-primary)也行,但前提很苛刻:上层必须是集群文件系统,比如 OCFS2 或者 GFS2,它们自己有分布式锁管理;普通 ext4/XFS 在两端同时挂载,几秒钟就把文件系统写坏了。dual-primary 另一个正当用途是虚拟机的 live migration——迁移的瞬间两端短暂同时为 Primary,由上面的集群管理器保证只有一个虚机实例在跑。别把 dual-primary 当成"提高性能"的手段,它不是。

版本上说一句:DRBD 8 是双节点,就是最经典的"一主一备"。DRBD 9 支持超过 2 个节点,也支持堆叠(stacked)配置,可以做"本地同城三副本 + 异地再叠一层"这种结构。如果你现在还是 8.4 的老版本,且只有两个节点,那升不升级取决于你要不要第三个副本;单纯两节点场景,8 和 9 的核心机制是一样的。

三种复制协议:A 快、B 折中、C 安全,选错就是选风险

DRBD 的复制协议只有 A、B、C 三个,区别全在"什么时候向上层返回写成功"。这一句话决定了你的数据安全性,也决定了你的写入延迟。别被名字骗了,这三个不是"低中高三档配置",是三种不同的风险交换。

协议 何时返回写成功 对端掉电会丢什么 对端宕机会丢什么 写入延迟构成 适合什么场景
Protocol A(异步) 本地写完成,且数据已放入发送缓冲区即返回,不等对端收到、更不等落盘 会丢:缓冲区里还没发走的那些写 也会丢:发送缓冲区里的数据随内存一起没了 约等于本地写延迟,几乎不受网络影响 跨城/跨境异地容灾副本、对延迟零容忍且能接受丢最近几秒写入的业务
Protocol B(半同步) 本地写完成,且数据已发送到对端(到达对端内存)即返回,不等对端落盘 会丢:对端内存里还没落盘的那部分 不丢:对端已收到并正常处理,属于干净宕机 本地写 + 单向网络发送时间 同城机房、能接受"对端整机掉电才丢数据"这一前提的折中方案
Protocol C(同步) 本地与对端都写完成(落盘)才返回 不丢:返回成功即意味着两端都已落盘 不丢:同上,宕机与掉电都不影响已确认的写 本地写 + 网络往返 + 对端写,延迟被 RTT 直接加上去 同城低延迟链路上的主用方案,金融交易、订单库这类不能丢数据的业务

Protocol A:把风险换成了速度

A 是异步。本地写完、数据塞进发送缓冲区就向上层报告成功,至于对端有没有收到、有没有落盘,它不等。好处是延迟基本等于本地磁盘的延迟,网络好坏对写入性能影响很小,跨城跨境都能跑。代价是:对端这台机器只要出问题——不管是掉电还是宕机——发送缓冲区里那些还没发走、或者发了但收方还没处理的写,就没了。丢的是"最近几秒的写入",具体多少取决于当时的网络状况和缓冲区积压量,以实测为准。

Protocol B:一个经常被跳过、其实挺实用的中间档

B 是半同步,写请求要真正发到对端、进入对端的内存才算完成,但不等对端写进磁盘。这个区分很关键:对端如果是正常的软件崩溃、正常关机、正常重启(也就是内存里的数据能被正常处理掉的情况),数据不丢;但如果对端整机掉电,内存里那些还没落盘的写就丢了。实际运维里,A 和 C 用得最多,B 常被忽略,其实在同城机房这种掉电概率极低的场景,B 是个很划算的折中——它比 C 少了一个"等对端写盘"的时间,又比 A 多了一层"至少数据已经到对端机器上"的保证。

Protocol C:最安全,也最诚实

C 是同步,本地和对端都落盘了才返回写成功。从数据安全角度讲这是最干净的:只要上层收到了成功,数据就在两台机器的磁盘上各有一份。代价也最实诚——写入延迟 = 本地写 + 网络往返 + 对端写。注意这里面"网络往返"是 RTT,不是带宽除以数据量。哪怕你的带宽再大,RTT 那一截时间是省不掉的。

Protocol C 的延迟账:跨机房会把 fsync 拖成什么

这一节单独拎出来讲,因为它是 DRBD 落地时最容易踩的坑,而且是"配置什么都对了但就是慢"的那种坑。

数据库的刷盘操作对延迟极其敏感。redo log 的 fsync、binlog 的 sync、checkpoint 期间的脏页刷盘——这些操作的频率非常高,而且很多是串行的。在 Protocol C 下,每一次这样的操作都被加上了一个完整的网络往返。同城机房之间 RTT 通常在毫秒以内甚至更低,这一截可以接受;一旦跨城,RTT 上到几十毫秒量级,跨城跨境更高(具体数值以实测为准),你的事务提交延迟就是被这个数字硬生生垫高的。

这里有个很常见的误解,得点破:带宽大不等于延迟低。很多人觉得"我把复制链路换到万兆就好了",换完发现 fsync 该慢还是慢。因为瓶颈根本不在传输时间上——一个 4KB 的块在万兆上传输的时间可以忽略不计,卡你的是那一来一回的等待。所以判断能不能用 Protocol C,先看 RTT,再看带宽。

那跨机房到底怎么配?我的立场很明确:同城用 C,异地用 A。跨城的那一端如果也上 C,等于把自己数据库的写性能按在地上摩擦,换来一个"理论上不丢数据"的安慰。真要做异地容灾,老老实实用 A 协议做异步副本,同时在应用层或者数据库层再考虑一份逻辑备份/延迟从库,比硬上 C 靠谱得多。

还要提醒一点:Protocol C 下,如果复制链路抖动、丢包重传,延迟会瞬间放大。所以复制链路本身的稳定性比它的峰值带宽更重要。有条件的话给复制单独走一块网卡、单独划一个网段,别和业务流量、备份流量挤在一起——备份流量一上来把复制链路挤爆,你会看到同步延迟突然拉大,数据库跟着卡。

元数据放哪:内置省心,外置快

DRBD 的元数据(metadata)记的是两样东西:activity log(AL,活动日志)和 bitmap(位图)。bitmap 用来标记哪些块和对方不一致,重同步时按它来;AL 记录最近写入的热区,下面一节细说。

internal meta-disk:省心,但元数据跟数据抢 IO

内置元数据就是把元数据放在和数据同一块盘的末尾区域。好处是配置简单,不需要额外的盘位,两台机器各一块盘就能跑起来。坏处是元数据和数据在同一块盘上争 IO——机械盘上这个冲突特别明显:磁头要在数据区和元数据区之间来回寻道,本来是顺序的写入被撕成随机的。你要是在机械盘上用 internal metadata 跑写入密集的业务,元数据写会变成一块看不见的性能税。

external meta-disk:快,代价是多一个盘位

外置元数据是单独拿一块盘或者一个分区专门放元数据。元数据写是典型的随机小 IO,放在能扛随机写的介质上就对了——SSD 或者 NVMe 明显比机械盘合适(具体提升幅度以实测为准)。代价是需要额外的盘位,租用服务器的时候要提前确认机器能不能加盘、有几个盘位。

我的建议很直接:只要机器还有盘位,就上 external meta-disk,哪怕只拿一块小容量的 SSD 单独做元数据盘。这块盘不需要大,元数据总量和你的数据盘容量、al-extents 设置有关,通常不需要太大的空间,但它扛的是随机写,介质要好。拿一块企业级的 SATA SSD 甚至 NVMe 做元数据盘,是整个方案里性价比最高的一笔投入。

activity log 决定了掉线重连要同步多少

activity log(AL,活动日志)是 DRBD 里最容易被忽略、但对故障恢复时间影响最大的一个机制。

它的逻辑是这样的:节点正常运行期间,DRBD 把"最近被写过"的区域记录在 AL 里,每个区域叫一个 extent。当对端短暂掉线(网络抖一下、机器重启一下)又重新连上来时,DRBD 不需要扫描整个磁盘去比对,只需要把 AL 覆盖的那部分区域重新同步一遍就行——因为除了这些热区,其余地方要么一直没写过、要么早就同步完了。这就是"短暂掉线几分钟,重连后几秒钟就同步完了"的原因。

关键参数是 al-extents,也就是 AL 里能记录多少个 extent。这个参数是个两头堵的权衡:

  • al-extents 太小:热区频繁换进换出,每换一次都要写一次元数据,元数据盘的写压力陡增,在 external meta-disk 上是随机小 IO 暴增,在 internal meta-disk 上就是机械盘磁头来回跑。
  • al-extents 太大:AL 覆盖的区域变大,节点重连时要重同步的数据量也跟着变大,本来几秒能完成的重同步变成几分钟。

怎么调?没有放之四海皆准的值,得看你业务的写入模式:写入集中在少数几个热区的(比如数据库的 redo log 区域),小一点的 AL 就够;写入很分散、随机写满盘跑的,AL 得调大,否则元数据写会打爆。调整之前先在测试环境用你自己的业务负载压一遍,看元数据盘的写 IO 和重同步耗时,以实测为准。别照抄网上的配置片段,那些参数都是针对别人的负载调出来的。

重同步为什么要限速:不吃限速就吃掉业务 IO

重同步(resync)是节点重连后按 bitmap 把不一致的块补齐的过程。它有两个触发场景:一个是上面说的短暂掉线后按 AL 做局部同步,量不大;另一个是长时间断连、新节点加入、或者整块盘换过之后的全量 resync——这个量是按磁盘容量算的,几百 GB 到几 TB 都很常见。

全量 resync 如果不限速,会发生什么?它会把 replication 链路的带宽吃满,同时在对端和本端都产生大量的顺序读 + 顺序写,直接和业务 IO 抢磁盘。结果就是:同步在进行的时候,业务侧的 IO 延迟明显上升,数据库慢查询堆积,用户能感觉到卡。这时候运维往往陷入两难——不让它同步完,数据没有冗余保护;让它跑完,业务卡几个小时。

所以限速是必须的。DRBD 9 用 c-max-rate 控制同步的最大速率(DRBD 8 时代对应的是 syncer 的 rate 配置)。还有 c-min-rate 这个下限,配合动态同步速率控制器使用:DRBD 会监测对端的网络/磁盘拥塞情况,在保证不低于 c-min-rate 的前提下动态调整,业务空闲时跑快点,业务忙时自动让路。这套机制在 DRBD 9 上是默认可用的,比老版本手动卡一个固定值聪明得多。

具体限到多少?经验做法是:先测出你的复制链路在不影响业务的前提下能持续吃多少带宽,再给 resync 留一个安全余量。写入密集的业务,我会把 resync 上限压得比较狠,宁可同步慢一点,也不能让业务抖。反正同步是后台的事,晚几个小时完成不影响正确性,只影响这段时间的冗余度。

脑裂是怎么发生的:网络分区时两端都成了主

前面那些都是"慢"的问题,慢还能忍。脑裂(split-brain)是"数据错了"的问题,这个忍不了。

脑裂的定义很简单:两个节点都认为自己是 Primary,并且各自接受了写入。这时候两份数据都在往前走,但走的是不同的路。等网络恢复,DRBD 发现两边的 bitmap 都对不上,而且自己不是简单的"一方落后一方领先"——两边都有对方没有的新数据。这时候它没法自动判断该听谁的,只能标记 Split-Brain detected,断开连接,然后在日志里明确报出来,等人来处理。

典型触发场景

成因其实就一句话:心跳/复制链路断了,但业务网还通着。DRBD 只知道"我跟对端失去联系了",它不知道对端是死了、还是只是自己看不见它。如果这时候上层还有别的东西把两端都提升成 Primary(或者两端各自被提升),脑裂就发生了。拆开看,常见触发有三类:

  • 网络分区(network partition):复制链路/心跳链路中断,两台机器其实都活着,也都还在对外提供服务。这是最典型的,也是危害最大的——因为两端都在持续写入新的业务数据。
  • 集群管理器误判:Pacemaker/Corosync 层面的消息延迟、quorum 计算出错,导致它认为主节点已失效,把备节点提升为主,而老主其实还活着还在写。
  • 手工误操作:这个比例一点都不低。运维在维护窗口里手动 drbdadm primary,忘了先确认对端状态;或者在故障演练时执行了错误的命令序列。说白了,就是人手滑了。

要特别强调一点:脑裂不是"复制失败",复制本身可能工作得好好的。它是"协调失败"。所以你把所有注意力放在调优复制性能上,不解决协调问题,脑裂该来还是会来。

DRBD 不负责决定谁该活:fencing 才是答案

这一节是整篇文章最重要的一节,如果你只记一句话,记这句:DRBD 镜像数据,但不决定谁该活。决定谁该活的是 fencing。

什么是 fencing?就是把失联的那个节点"真正隔离掉"——不是让它停止服务,而是让它物理上不可能再写磁盘。最彻底的是 STONITH(Shoot The Other Node In The Head),通过电源 fence 设备、服务器的带外管理口(IPMI / iLO / iDRAC 这类)把对方强制断电或者重启。断电之后,它就不可能再往本地磁盘写一个字节,脑裂在物理层面被杜绝了。

没有 fencing 的双机热备是什么?是一套"看起来有冗余、实际上随时可能两边同时写"的系统。你觉得你在做高可用,其实你在赌网络不会分区。这个赌注在同城机房里胜率还行,一旦拉长距离、链路质量下降,赔率就很难看了。

在软件层面,这件事由 Pacemaker + Corosync 承担:Corosync 负责节点间的心跳与成员关系,Pacemaker 负责资源编排,配合 STONITH 资源类型实现真正的隔离。这也是为什么我一直强调——DRBD 只是这套方案里的"数据搬运工",真正的高可用是 Pacemaker/Corosync + STONITH + DRBD + VIP + 应用资源代理共同构成的。少了 STONITH 那一环,剩下的都叫"数据镜像",不叫"高可用"。

这里还有一个不得不提的现实问题:你租的服务器,有没有可用的 fence 手段?如果你手上是一台普通租用服务器,没有带外管理口、也没有接入可远程控制的电源,那 STONITH 就无从谈起,你只能退而求其次做"资源级 fencing"——比如通过交换机端口隔离、或者至少确保失联节点无法对外提供服务。但这些都不如断电彻底。所以做双机热备之前,先跟机房确认带外管理(IPMI/iLO)是否可用、能不能授权给你的集群软件调用。这件事应该在下单之前问清楚,而不是在配置 Pacemaker 的时候才发现没有。

脑裂恢复:discard-my-data 按下去之前先想清楚

脑裂已经发生了,日志里躺着 Split-Brain detected,连接是断开的。现在怎么办?

先判断,再动手

第一步绝对不是敲恢复命令。先搞清楚三件事:

  • 哪一端在真正对外提供服务?看 VIP 漂在谁身上、看应用的连接打到了哪台、看监控里的业务流量。有业务写入的那一端通常就是该保留的一端。
  • 两端各写了多少、写了什么?看两端的状态信息、看应用的日志,判断哪一边的变更是"真实业务产生的"。
  • 能不能先保一份现场?如果条件允许,先对要丢弃的那一端做磁盘快照或者整盘备份,再执行恢复。这一步很多人嫌麻烦跳过,然后恢复完才发现丢错了。

恢复命令本身很简单,难点在选边

确认好保留端之后,操作就两条命令:

  • 在要被丢弃的那一端执行:drbdadm -- --discard-my-data connect <res>
  • 在要保留的那一端执行:drbdadm connect <res>

--discard-my-data 这个参数名已经说得很清楚了:丢弃我这份数据。执行之后,这一端会把自己的数据作废,从对端全量重新同步。也就是说——选错端就是真的丢数据,而且是不可逆的。这个命令没有确认提示、没有后悔药。

我的操作习惯是:动手之前,把两端的角色、连接状态、各自的变更量级都截图留存,并且让第二个人复核一次"我们要丢哪一端"。这不是形式主义,脑裂现场往往是在凌晨、在被催着恢复业务的情况下处理的,人很容易搞反。

恢复完成后,别急着宣告胜利。还要回头查两件事:一是脑裂的根因是什么(网络抖了?集群配置有问题?有人手滑了?),二是 fencing 为什么没起作用。不解决根因,下一次脑裂只是时间问题。

自动恢复策略 after-sb-*:方便但容易替你做错决定

DRBD 提供了一组自动脑裂恢复策略,用三个参数覆盖三种情况:after-sb-0pri(脑裂时两端都不是 Primary)、after-sb-1pri(只有一端是 Primary)、after-sb-2pri(两端都是 Primary)。每个参数可以配成几种行为,常见的有:

  • disconnect:不自动恢复,直接断开连接,交给人工处理。这通常是默认配置。
  • discard-younger-primary:丢弃"较晚成为 Primary"的那一端的数据。
  • discard-least-changes:丢弃"变更量较少"的那一端的数据。
  • panic:直接让节点 panic,把问题彻底暴露出来。

为什么我不太建议在生产库上开自动策略

这些策略听起来很美好——半夜不用起床了。但它们的判断依据是有问题的:

discard-least-changes 按"变更量"决定谁活。可是变更量小不等于不重要。举个真实的场景:一端跑了几个小时的批量写入,变更量大;另一端刚被提升为主,只接了几十笔订单写入,变更量小。按这个策略,订单那端的数据被丢了。你说这合理吗?

discard-younger-primary 按"成为 Primary 的时间先后"决定,依赖两端的时钟。时钟不准怎么办?更麻烦的是,在真正的网络分区里,两端被提升为 Primary 的时间可能非常接近,谁"更晚"本身就带随机性。

panic 是最诚实的一个——它不替你做决定,它把问题喊出来。但在生产环境让节点直接 panic,代价也不小。

所以我的立场是:核心数据库用默认的 disconnect,让人工来判;只有在非常确定的场景(比如 after-sb-0pri,两端都没被提升为主、没有新写入,这时候自动恢复的风险确实低)才考虑放宽。把"半夜不用起床"当成目标,最后往往是"早上起来发现数据丢了"。

一万网络的两个推荐项

#1 一万网络「裸金属 E5-2698v4×2」——双机热备主力节点的务实选择

做 DRBD 双机热备,主节点我一般首推裸金属而不是云主机,理由很实在:块级复制对磁盘 IO 的占用是持续且真实的,虚拟化层再来一层调度,延迟的抖动就不好控制了。裸金属没有这一层,磁盘性能是直给的,你测出来的延迟就是业务能拿到的延迟。

一万网络的裸金属 E5-2698v4×2 官网明示价 ¥3999 起(以官网实时价为准)。这个配置放在 DRBD 场景里有几个点很对路:双路 CPU 给足了核数,DRBD 本身的 CPU 开销不大但 resync 期间、还有数据库本身都要算力;更重要的是裸金属通常盘位和内存槽位都有余量,你可以加一块小容量 SSD 单独做 external meta-disk——前面说过,这是整个方案里性价比最高的一笔投入。另外一万网络深耕 IDC 19 年(成立于 2007 年),深圳南山总部、自营机柜最快 1 分钟上架,机器是全新超微、DELL 品牌机,做双机这种要长期稳定跑的方案,硬件底子稳不稳比参数漂亮更重要。

下单之前我建议你顺手确认三件事:这台机器有没有带外管理口(IPMI/iLO)可供 STONITH 调用、能不能加盘做独立元数据盘、复制链路能不能单独走一块网卡。这三件事决定了你这套双机热备是"真高可用"还是"看起来高可用"。

#2 一万网络「一万云」——拿来做仲裁节点和第三副本

双机最尴尬的地方是"两票制":两台机器,断开了谁也不知道对方是死是活,quorum 无从计算。加第三个节点——哪怕它性能很弱——就能把两票变成三票,集群的判定逻辑立刻清晰很多。一万云 ¥25 起(以官网实时价为准),这个价位拿来做仲裁节点、监控节点、或者 fence 代理节点非常合适,它不需要算力,只需要稳定在线、能被两边都访问到。

如果你用的是 DRBD 9,还能更进一步:把第三个节点做成一个真正的副本节点,配合堆叠配置做"同城三副本 + 异地再叠一层"。这种结构下你既拿到了三副本的容错,又不用在跨城链路上硬跑 Protocol C。另外一万云配一万网络的免费系统盘快照(每日 3 份 / 30 秒回滚)也很实用——在执行 --discard-my-data 这种不可逆操作之前先打一份快照,成本几乎为零,但给你留了一条退路。

顺带说一句工程支持

一万网络的 7×24 中文工单平均 5 分钟响应、硬件故障 10 分钟自动迁移,这两条放在双机场景里的价值比单机的地方大得多——双机坏了一台,你最怕的是"等着有人来处理"的这段时间里另一台也出问题。网络方面 BGP 多线 + CN2 GIA 回国低延迟,节点覆盖华南/华东/华北/中国香港/海外,做同城双机或者异地副本都能在同一个服务商体系里配齐,不用跨服务商拉链路。资质方面持增值电信业务经营许可证、国家高新技术企业、专精特新;涉及行业合规的,可提供合规咨询与架构建议。

选型清单:磁盘、元数据盘、网络带宽怎么配

把前面所有内容收敛成一份可以直接拿去对照配置的清单:

磁盘

  • 容量必须两端一致。小的那一端会把大的那一端也限制住,多出来的容量是浪费。
  • 最好同型号同规格。Protocol C 下每一次写都在等对端,写入延迟对齐到慢的那一端。你本地是 NVMe、对端是机械盘,那就是按机械盘跑。
  • 按数据盘 + 元数据盘两块来规划。别指望一块盘又扛业务顺序写又扛元数据随机写。

元数据盘

  • 介质选 SSD 或 NVMe。元数据写是随机小 IO,机械盘在这类负载上很难看(性能差异以实测为准)。
  • 容量不用大,但耐用性要好。元数据写频繁,写入放大对小容量盘是考验。
  • 有盘位就上 external meta-disk。internal 只在没得选的时候用。
  • al-extents 按自己的写入模式调,别照抄网上的配置片段,调之前先压测。

网络

  • Protocol C 下带宽必须 ≥ 业务写入带宽,并且要留 resync 余量。写入密集场景千兆可能不够,这个判断要基于你实测的写入带宽来算,不是凭感觉。
  • 先看 RTT 再看带宽。决定 fsync 延迟的是往返时间,不是峰值吞吐。跨机房上 C 之前先量 RTT。
  • 复制链路单独走一块网卡、单独划网段,不要和业务流量、备份流量共用。链路稳定性比峰值带宽更重要。
  • 异地副本用 Protocol A,别硬上 C。

fencing 能力(这条最容易被漏掉)

  • 带外管理口(IPMI/iLO/iDRAC)是否可用、能否授权给集群软件调用。没有这个,STONITH 无从谈起。
  • 有没有可远程控制的电源 fence 设备。这是最彻底的隔离手段。
  • 至少准备一个退而求其次的资源级隔离方案,比如交换机端口隔离,保证失联节点无法对外服务。

软件栈

  • DRBD 只做镜像,切换要另配:Pacemaker + Corosync + VIP + 应用资源代理,缺一不可。
  • STONITH 是必选项不是可选项。
  • 脑裂策略保持默认 disconnect,让人工判断。

五个容易踩的坑,以及怎么避

坑一:只看带宽不看 RTT,跨机房硬上 Protocol C

为什么坑:Protocol C 的延迟里有一项是网络往返时间,这部分跟带宽无关。你以为换了大带宽就不慢了,结果 fsync 该慢还是慢,最后得出"DRBD 性能不行"的错误结论,把方案整个否定掉。

怎么避:先量两端之间的 RTT,再决定协议。同城低延迟才上 C;跨城、跨境一律考虑 A,把 C 留给近距离链路。判断标准是你的业务能接受多高的写延迟,以实测为准。

坑二:元数据放内置盘,而且数据盘还是机械盘

为什么坑:元数据写是随机小 IO,和数据区的顺序写在机械盘上互相打架,磁头来回寻道,把本来能跑满的顺序写撕成随机写。表现出来的现象是"磁盘性能莫名其妙上不去",而你查数据的顺序读写测试可能还是正常的。

怎么避:加一块 SSD/NVMe 做 external meta-disk。这块盘不用大,但一定要是固态。下单前先确认机器有富余盘位,没有盘位就选能加盘的物理规格。

坑三:没配 fencing 就上自动切换

为什么坑:没有隔离手段的自动切换,等于在给脑裂铺路。集群管理器一误判,就把备机提升为主,而老主还在写,两份数据就此分道扬镳。这时候你不但没有高可用,还多了一个数据一致性问题要处理。

怎么避:STONITH 先配好、先演练过,再开启自动切换。没有带外管理口就在选型阶段换一家能提供的,或者至少做到资源级隔离。演练的时候故意把主节点的复制链路断掉,看它是不是真的被隔离了,光看配置是看不出来的。

坑四:全量 resync 不限速

为什么坑:几 TB 的数据全速同步,会把复制链路带宽吃满,同时在两端产生大量顺序读写,直接和业务抢 IO。表现是同步期间业务明显变慢、数据库慢查询堆积,严重时超时报错。而这时候你往往正处在"刚换过盘、没有冗余"的脆弱期。

怎么避:配好 c-max-rate 上限,DRBD 9 上配合 c-min-rate 和动态速率控制器使用,让它在业务忙时自动让路。宁可同步慢一点,也不要让业务抖。同步是后台任务,晚几小时完成不影响正确性。

坑五:双机磁盘规格不一致,或者直接开 dual-primary 挂普通文件系统

为什么坑:前者会让 Protocol C 的写入延迟对齐到慢的那一端,你花在好盘上的钱一分都体现不出来;后者更狠——普通 ext4/XFS 在两个 Primary 上同时挂载,没有分布式锁管理,文件系统在极短时间内就会被写坏,而且这种损坏往往是静默的,等你发现的时候已经不好救了。

怎么避:双机磁盘容量、型号、规格保持一致,这是硬要求。dual-primary 只在两种情况下用:上层是 OCFS2/GFS2 这类集群文件系统,或者是虚拟机 live migration 这种短暂状态。除此之外一律单主模式。

读者最常追问的七个问题

Q1:DRBD 和数据库自带的主从复制,能互相替代吗?

不能互相替代,它们是不同层面的东西。数据库主从工作在逻辑层,复制的是 SQL 语句或者逻辑行变更(row-based 的 binlog 也是逻辑语义),能理解"这张表的这一行改了";DRBD 工作在块层,复制的是磁盘块,它不知道上面跑的是什么、改的是哪一行。带来的差异很实际:主从复制可以只传变更、可以做延迟从库、可以过滤库表;DRBD 只能按块传,删一个 1KB 文件也是一堆块写。反过来,DRBD 不挑数据库、不挑版本、不用改应用,主从则受数据库类型和版本限制。真要做高可用,常见做法是 DRBD 负责存储层的冗余,再叠加数据库自己的逻辑备份做兜底。

Q2:Protocol A、B、C 到底选哪个?

看你能接受丢多少、以及两端之间多远。同城机房、数据一条都不能丢的,上 C;同城但对延迟极其敏感、且能接受"对端整机掉电才丢最近几秒写入"这个前提的,B 是个被低估的选择,它比 C 少了一个等对面写盘的时间;跨城、跨境的副本一律考虑 A,因为 C 会把 RTT 直接加进每一次 fsync,写性能代价太大。还有个务实的组合:同城双机跑 C 作为主用,异地再加一个 A 协议的副本做容灾,兼顾数据安全与写性能。

Q3:跨机房能用 Protocol C 吗?

技术上能,工程上我一般不推荐。原因不是带宽不够,而是 RTT 太高:每一次 fsync 都要等一个完整的网络往返,跨城的 RTT 会直接垫高事务提交延迟(具体数值以实测为准)。而且链路一旦抖动丢包,延迟还会瞬时放大。真要跨机房,把 C 用在同城这段,异地那段用 A 做异步副本,这是最合理的结构。如果你的业务确实要求跨机房也不能丢数据,那应该从应用架构上想办法(比如两阶段提交、或者接受更长的提交延迟),而不是指望 DRBD 协议解决。

Q4:元数据一定要单独一块盘吗?

不强制,但我强烈建议。internal meta-disk 能用,配置也简单,代价是元数据写和数据写在同一块盘上争 IO——机械盘上这个冲突尤其严重,磁头来回寻道会把顺序写撕碎。external meta-disk 只需要一块不大的 SSD/NVMe,专门扛元数据那种随机小 IO,性能改善很明显(幅度以实测为准)。这笔投入在整个方案里占比很小,回报却是最直接的。前提是机器要有富余盘位,租用服务器的时候提前确认这一点。

Q5:脑裂发生了,第一件事该做什么?

绝对不是敲恢复命令。先判断两端谁在真正对外提供服务——看 VIP 漂在哪台、应用的连接打到了哪台、监控里哪台有业务流量,有真实写入的那一端通常就是该保留的一端。然后看两端各自的变更量级和内容,确认哪边的变更是业务产生的。条件允许的话,先对要丢弃的那一端做磁盘快照或整盘备份。全部确认完,再在丢弃端执行 drbdadm -- --discard-my-data connect <res>、保留端执行 drbdadm connect <res>。选错端就是真丢数据,这个命令没有后悔药。

Q6:after-sb-* 自动恢复策略能不能开?

核心业务库我建议保持默认的 disconnect,让人工判断。理由是这些自动策略的判断依据不靠谱:discard-least-changes 按变更量决定,但变更量小不等于不重要——跑了几小时批量的一端变更大,刚接了几十笔订单的一端变更小,按策略反而把订单丢了;discard-younger-primary 依赖两端时钟,时钟不准或者两端提升时间非常接近时就带随机性。比较安全的是 after-sb-0pri(两端都没被提升为主、没有新写入),这种场景放宽自动恢复的风险确实低。2pri 的场景一律人工处理。

Q7:租服务器做双机热备,最容易被忽略的硬件要求是什么?

带外管理口。几乎所有人在选型时都把注意力放在 CPU、内存、磁盘、带宽上,唯独忘了问一句"这台机器有没有 IPMI/iLO,能不能授权给我的集群软件调用"。没有带外管理,STONITH 就无从谈起,fencing 退化为资源级隔离,脑裂的风险实打实摆在那里。其次容易漏的是盘位——想做 external meta-disk 却发现机器加不了盘。第三是能不能给复制单独一块网卡。这三件事都应该在下单之前跟服务商确认清楚,而不是等配 Pacemaker 的时候才发现硬件不支持。

结论:先想清楚能不能接受丢最近几秒的写

DRBD 是个很老、很朴素的方案,朴素到它只做一件事:把一块盘实时抄一份给另一台机器。它吃的是磁盘顺序写、网络带宽、元数据盘的随机 IO 这三样资源,CPU 和内存基本不用操心。你要做的第一个决定是选 A、B 还是 C——这个决定的本质不是"性能调多少",而是"我愿意用多少数据安全换多少延迟",A 把风险换成速度,C 把速度换成安全,B 在中间,选错了就是选错了风险类型,不是配置没调好。

你要做的第二个决定,也是更重要的那个,是 fencing 怎么落地。别被"双机热备 = 不丢数据"这句话忽悠了,DRBD 自己不知道谁该活着,没有 STONITH 的双机,本质上是一套在赌网络不会分区的镜像系统。能接受丢最近几秒写入的业务,用 A 或 B、把 fencing 做扎实,跑得很舒服;一条都不能丢的,老老实实同城 C + 真隔离 + 异地异步副本,同时接受写入延迟变高这个事实。想两头都要的,最后通常两头都没拿到。

数据来源与报价说明

本文涉及的 DRBD 机制描述(块层复制、Protocol A/B/C 语义、Primary/Secondary 角色、internal/external meta-disk、activity log 与 al-extents、resync 与 c-max-rate/c-min-rate、脑裂检测与 --discard-my-data 恢复、after-sb-* 策略、barriers)均基于 DRBD 公开的技术文档与通用实现机制整理;涉及延迟、带宽、同步耗时等定量描述均为量级说明,具体数值以实测为准。

文中提及的一万网络产品与价格:裸金属 E5-2698v4×2 ¥3999 起、一万云 ¥25 起,属官网明示档位,以官网实时价为准;其余涉及配置、报价与规格的表述,若非官网明示,均为参考性说明,以咨询为准(预估)。服务与资质信息以一万网络官网公布内容为准,涉及行业合规的部分仅提供架构建议与合规咨询协助。

更多产品、价格与服务详情请见:https://www.idc10000.net/。本文所列价格与配置仅供参考,具体以签约时最新报价与合同为准。


上一篇:迁 ARM 服务器卡住的地方不在算力:先把依赖清单拉出来逐项过一遍

下一篇:说要 99.9% 之前先换成分钟:SLO 和错误预算怎么决定你要买几台服务器