☰
CubeFS 故障域(Fault Domain)配置与管理实战指南
2026/10/4 1:55:56 网站建设 项目流程
  • 存储
  • 分布式文件系统
  • 对象存储
  • 云原生

【免费下载链接】cubefs

cloud-native distributed storage

项目地址:https://gitcode.com/gh_mirrors/cu/cubefs
点击查看免费下载

故障域(Fault Domain)是 CubeFS Master 提供的一种数据分布规划能力,用于解决多 Zone 场景下副本集(copyset)分布缺乏规划的问题,通过将数据副本按"故障域 + NodeSet Group"维度做隔离编排,从而提升数据耐久性。本文基于 docs-zh/source/dev-guide/admin-api/master/failureDomain.md 并结合仓库源码,完整讲解故障域的启用条件、两级配置(Cluster/Volume)、启用决策矩阵、管理命令及底层实现原理,帮助你在一套已运行的 CubeFS 集群上安全、正确地开启并运维故障域。

为什么需要故障域

在多 Zone(跨机房/跨可用区)部署的 CubeFS 集群中,如果没有故障域规划,Master 在创建数据分区(Data Partition)时只会从可用 Zone 中按普通策略挑选节点,副本集的分布是"无规划"的——多个副本可能被分配到同一个 Zone 甚至同一批物理机架上,一旦该 Zone 或机架整体故障,整个副本集将同时丢失,数据的耐久性(durability)无法得到保证。

故障域机制将集群资源组织为Domain(故障域)→ NodeSet Group → NodeSet → 节点的分层结构(见 master/topology.go 中的DomainManager与DomainNodeSetGrpManager),在创建数据分区时强制从不同的 NodeSet Group 中挑选副本主机,使同一副本集的所有副本分布在相互隔离的故障区域内,即使单个区域整体宕机,其他区域中的副本仍能保证数据可读可恢复。

升级及配置项

故障域不是默认开启的能力,需要在Cluster 级别和Volume 级别分别配置,两者配合才能生效。文档原文中的配置小结明确指出:FaultDomain默认值为false,不加该配置则 Master 无法区分新建的 Zone 是"故障域 Zone"还是"归属于原有 cross_zone 的普通 Zone"。

Cluster 级别配置

在 Master 配置文件中新增如下配置项(对应源码中的配置解析键faultDomain,见 master/config.go 与 master/config.go):

FaultDomain bool # 默认false

在源码实现中,该配置项最终被赋值给Cluster.FaultDomain字段(见 master/cluster.go:c.FaultDomain = cfg.faultDomain),并同步到 Master 的 Raft 元数据状态机中持久化(metadata_fsm_op.go中会维护domainExcludeZones、domainNodeSetGrpVec等故障域状态)。也就是说,开启故障域意味着 Master 需要重启、配置需要更新,并且会同步管控现有 Volume 的更新策略。

除开关本身外,源码还提供了两个与之配套的进阶配置项(同为faultDomain前缀,见 master/config.go):

配置项作用
faultDomainGrpBatchCnt批量构建 NodeSet Group 的批次数
faultDomainBuildAsPossible是否尽可能构建 NodeSet Group(即使资源不足也尽量组组)

Volume 级别配置

Volume 级别保留原有的crossZone配置,并新增default_priority:

crossZone bool # 跨zone default_priority bool # true优先选择原有的zone,而不是从故障域里面分配
  • 保留项crossZone:标识该 Volume 是否跨 Zone 部署,是判断 Volume 是否"启用跨 Zone 能力"的基础开关。
  • 新增项default_priority:当 Volume 同时开启跨 Zone 时,若该值为true,Master 会优先在原有普通 Zone 中分配资源;只有原有资源不足时才进入故障域分配。

在源码中,与这两个 Volume 属性对应的键分别为crossZone与normalZonesFirst(见 master/const.go)。注意:文档中的default_priority与 API 参数中的normalZonesFirst是同一个概念的两种叫法——在创建 Volume 的 HTTP API 参数里使用normalZonesFirst,它在创建 Volume 时被映射为 Vol 的DefaultPriority字段(见 master/cluster.go)。

配置小结与生效决策

文档给出了三组前置约束,务必逐条对照你的集群现状:

  1. 对于现有的 Cluster(无论自建还是社区版、单 Zone 还是跨 Zone):若需要启用故障域,必须保证 Cluster 支持故障域(配置FaultDomain并重启 Master、更新配置),同时要管控现有 Volume 的更新策略;否则请继续沿用原有策略,不要强行开启。
  2. Cluster 支持但 Volume 不选择使用:Volume 继续沿用原有策略,并在原有 Zone 中分配资源;原有资源耗尽后再使用新 Zone(故障域)的资源。
  3. Cluster 不支持:Volume 无法启用自己的故障域策略。

当 Cluster 与 Volume 两级配置组合时,Volume 使用域资源的规则如下表(原文档核心表格,完整保留):

Cluster:FaultDomainVol:crossZoneVol:normalZonesFirstRules for volume to use domain
NN/AN/ADo not support domain
YNN/AWrite origin resources first before fault domain until origin reach threshold
YYNWrite fault domain only
YYYWrite origin resources first before fault domain until origin reach threshold

上述决策逻辑在源码中由Cluster.isFaultDomain(vol)实现(见 master/cluster.go)。其核心判断为:

  • Cluster 必须开启FaultDomain;
  • 且满足以下任一条件时该 Volume 进入故障域分配:
    • Volume 自身已开启domainOn(此前已判定为故障域 Volume);
    • Volume 未开crossZone但 Cluster 已进入"需要故障域"状态(needFaultDomain,即普通 Zone 资源已用尽,见 master/cluster.go);
    • 或 Volume 指定了 Zone 且该 Zone 状态为unavailableZone(不可用);
    • 或 Volume 开启crossZone且(default_priority为 false,或为 true 但普通 Zone 已用尽 / 非故障域 Zone 数量不超过 1)。

一旦判定为故障域 Volume,Master 会在创建数据分区时走getHostFromDomainZone(vol.domainId, ...)从指定 Domain 的 NodeSet Group 中分配副本主机,而不是普通的getHostFromNormalZone(...)路径(见 master/cluster.go)。这意味着故障域分配是"写路径"级别的强制行为,直接影响每个新数据分区的副本落点。

注意事项

故障域解决的是多 Zone 场景下 copysets 分布没有规划的问题,保证了数据的耐久性,但需要明确以下几点(原文档要点,逐条保留并补充源码依据):

  1. 启用故障域后,新区域中的所有设备都将加入故障域:Master 会将新建 Zone 纳入故障域管理,并在元数据状态机中维护domainExcludeZones(非故障域 Zone 列表,见 master/topology.go)与domainNodeSetGrpVec(故障域 NodeSet Group 列表,见 master/topology.go)。
  2. 创建的 Volume 会优先选择原 Zone 的资源:即default_priority=true的默认行为,只有原 Zone 资源耗尽(needFaultDomain置位)才会使用故障域资源。
  3. 新建卷时需要根据上表添加配置项使用域资源:默认情况下,如果可用,则首先使用原始 Zone 资源。也就是说,故障域能力开启 ≠ 所有 Volume 自动使用故障域,必须按前文决策矩阵显式配置crossZone与normalZonesFirst。

另外,原文档特别强调:原有数据不能自动迁移。故障域只影响启用后新创建的数据分区,存量数据分区不会自动搬迁,需要根据业务需求评估是否需要做数据重平衡或迁移。

管理命令

故障域相关的管理命令均通过 Master 的 HTTP Admin API 提供,端口默认为 Master 对外服务端口(示例中使用192.168.0.11:17010,请替换为你实际集群的 Master 地址)。各接口在 master/http_server.go 中注册路由,具体 handler 实现位于 master/api_service.go。

创建使用故障域的 Volume

curl "http://192.168.0.11:17010/admin/createVol?name=volDomain&capacity=1000&owner=cfs&crossZone=true&normalZonesFirst=false"

参数列表(原文档表格,完整保留):

参数类型描述
crossZonestring是否跨 zone
normalZonesFirstbool非故障域优先

在该示例中,crossZone=true、normalZonesFirst=false对应决策矩阵中"Write fault domain only"的规则——新建的volDomain卷只从故障域中分配副本资源。参数在创建 Volume 请求解析中被读取(crossZone与normalZonesFirst键定义见 master/const.go,解析位于 master/api_args_parse.go),最终写入 Vol 的DefaultPriority(见 master/cluster.go)。

查看故障域是否启用

curl "http://192.168.0.11:17010/admin/getIsDomainOn"

该接口由getIsDomainOnhandler 处理(见 master/api_service.go),返回结构SimpleDomainInfo,其中DomainOn字段直接取自m.cluster.FaultDomain。即:该命令返回的是 Cluster 级别的FaultDomain开关状态,用于确认故障域功能是否已在集群层面启用。

查看故障域使用情况

curl -v "http://192.168.0.11:17010/admin/getDomainInfo"

对应 handler 为getAllNodeSetGrpInfoHandler(见 master/api_service.go),返回proto.DomainNodeSetGrpInfoList,包含以下关键字段:

  • DomainOn:Cluster 是否开启故障域(同cluster.FaultDomain);
  • NeedDomain:是否已进入"需要故障域"状态(cluster.needFaultDomain,即普通 Zone 资源是否已用尽);
  • DataRatioLimit:故障域内数据使用比例上限(domainManager.dataRatioLimit);
  • ZoneExcludeRatioLimit:非故障域 Zone 的数据使用上限(domainManager.excludeZoneUseRatio);
  • ExcludeZones:非故障域 Zone 列表(domainExcludeZones);
  • DomainNodeSetGrpInfo:每个故障域(Domain)下的 NodeSet Group 列表,包含DomainId与Status状态信息。

查看故障域 copyset group 的使用情况

curl "http://192.168.0.11:17010/admin/getDomainNodeSetGrpInfo?id=37"

对应 handler 为getNodeSetGrpInfoHandler(见 master/api_service.go),除id参数外还支持可选的domainId参数,返回指定 NodeSet Group 的SimpleNodeSetGrpInfo详情。NodeSet Group 是故障域分配的核心单元:Master 在故障域内将节点划分为多个 NodeSet,再将 NodeSet 组合成 NodeSet Group(构建方法见 master/topology.go 的buildNodeSetGrp,以及buildNodeSetGrp3Zone、buildNodeSetGrp2Plus1、buildNodeSetGrpOneZone等不同 Zone 数场景的构建策略),创建数据分区时从 Group 内不同 NodeSet 挑选副本,从而保证副本跨故障域隔离。

更新非故障域数据使用上限

curl "http://192.168.0.11:17010/admin/updateZoneExcludeRatio?ratio=0.7"

对应 handler 为updateZoneExcludeRatioHandler(见 master/api_service.go),参数ratio为浮点数。源码中的校验逻辑表明:

  • ratio必须提供,否则报keyNotFound参数错误;
  • 解析为float64失败会报参数错误;
  • 与同类接口updateDataUseRatioHandler(master/api_service.go)的校验一致,ratio == 0或ratio > 1均视为非法参数。

该参数控制"普通(非故障域)Zone 资源使用的阈值上限":当普通 Zone 的数据使用量达到该比例后,Master 将needFaultDomain置位,后续创建的 Volume/数据分区开始使用故障域资源——这正是决策矩阵中 "Write origin resources first before fault domainuntil origin reach threshold" 所描述的阈值行为。

故障域分配流程与源码印证

将上述管理命令与源码结合,故障域的完整工作链路可以概括为:

  1. 初始化:Master 启动时解析faultDomain配置(master/config.go),赋值给Cluster.FaultDomain(master/cluster.go),并在 Raft 状态机恢复时重建domainExcludeZones与domainNodeSetGrpVec(master/metadata_fsm_op.go)。
  2. 资源组织:故障域内的节点被组织为 Domain → NodeSet Group → NodeSet 的层次结构,构建逻辑见 master/topology.go(含DomainManager、DomainNodeSetGrpManager、buildNodeSetGrp*系列函数)。
  3. 写路径判定:每次创建数据分区时调用isFaultDomain(vol)(master/cluster.go)判定当前 Volume 是否走故障域;走故障域则通过getHostFromDomainZone分配副本主机,否则走getHostFromNormalZone普通分配(master/cluster.go)。
  4. 运维查询:通过getIsDomainOn/getDomainInfo/getDomainNodeSetGrpInfo三个查询接口观测开关状态、使用情况与 Group 明细;通过updateZoneExcludeRatio动态调整普通 Zone 使用阈值。

结语

故障域是 CubeFS 面向多 Zone 生产环境提供的高可用增强能力,其正确使用依赖Cluster 级开关 + Volume 级策略的两级配合:先在 Master 配置中开启FaultDomain并重启生效,再按决策矩阵为每个 Volume 显式设置crossZone与normalZonesFirst。开启后,通过getIsDomainOn、getDomainInfo、getDomainNodeSetGrpInfo持续观测状态,并用updateZoneExcludeRatio控制普通 Zone 资源的耗尽阈值。需要特别留意的是,故障域只保证新数据分区的分布规划,存量数据不会自动迁移,升级前务必做好容量与数据布局评估。

  • 存储
  • 分布式文件系统
  • 对象存储
  • 云原生

【免费下载链接】cubefs

cloud-native distributed storage

项目地址:https://gitcode.com/gh_mirrors/cu/cubefs
点击查看免费下载
上一篇:ActionBarSherlock扩展视图:自定义View实现
下一篇:Czkawka 完整磁盘清理指南:一次扫描找出重复文件、空文件夹与相似图片

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询