CubeFS Blobstore Clustermgr 管理 API 实战指南:节点、磁盘、卷与后台任务全解析
存储分布式文件系统对象存储云原生【免费下载链接】cubefscloud-native distributed storage项目地址https://gitcode.com/gh_mirrors/cu/cubefs点击查看免费下载导读Clustermgr集群管理器是 CubeFS Blobstore 体系中负责元数据与集群状态管理的核心服务它基于 Raft 保证集群元数据的强一致并对外提供一套 HTTP 管理 API覆盖集群状态查看、Raft 节点增删与领导权切换、磁盘状态管理、卷信息查询以及后台任务开关等运维场景。本文以官方管理 API 文档docs/source/dev-guide/admin-api/blobstore/cm.md为主线结合仓库源码逐接口讲解请求格式、参数含义与底层实现原理帮助读者掌握用 curl 与 blobstore-cli 完成 Clustermgr 日常运维的核心技能。一、Clustermgr 管理 API 概览Clustermgr 的所有管理接口都通过 HTTP 暴露默认监听在127.0.0.1:9998。从路由注册源码 blobstore/clustermgr/handler.go 可以看到这些管理接口集中在文件末尾的manage分区中POST /member/add向 Raft 集群添加成员POST /member/remove从 Raft 集群移除成员POST /leadership/transfer切换 Raft 领导者GET /stat获取集群整体状态POST /config/set、GET /config/get、POST /config/delete配置键值读写以及磁盘、卷相关的GET /disk/info、POST /disk/set、POST /disk/drop、POST /disk/access、GET /volume/get等这些接口在 blobstore/api/clustermgr/client.go 中都有对应的 Go 客户端封装本文统一使用 curl 演示二者等价。二、服务状态查询GET /stat/stat返回 Clustermgr 的集群整体状态包括 Raft 状态、空间使用、卷统计等信息是运维排障的第一入口。curl http://127.0.0.1:9998/stat响应示例{ leader_host: 127.0.0.1:9998, raft_status: { applied: 291968826, commit: 291968826, leader: 3, nodeId: 2, peers: null, raftApplied: 291968826, raftState: StateFollower, term: 24, transferee: 0, vote: 3 }, read_only: false, space_stat: { disk_stat_infos: [ { available: 107, broken: 0, dropped: 10, dropping: 0, expired: 0, idc: z0, readonly: 22, repaired: 17, repairing: 0, total: 134, total_chunk: 55619, total_free_chunk: 37979 }, { available: 93, broken: 0, dropped: 10, dropping: 0, expired: 0, idc: z1, readonly: 22, repaired: 19, repairing: 0, total: 122, total_chunk: 51523, total_free_chunk: 33425 }, { available: 96, broken: 0, dropped: 53, dropping: 1, expired: 0, idc: z2, readonly: 46, repaired: 3, repairing: 0, total: 152, total_chunk: 58123, total_free_chunk: 40173 } ], free_space: 1774492930453504, total_blob_node: 17, total_disk: 408, total_space: 2155017090891776, used_space: 380524160438272, writable_space: 923847465369600 }, volume_stat: { active_volume: 345, can_alloc_volume: 1651, idle_volume: 1651, lock_volume: 0, total_volume: 1996, unlocking_volume: 0 } }响应字段可分成三组来理解raft_statusRaft 协议运行细节包括当前nodeId、term、leader、vote、applied/commit日志水位以及raftStateStateFollower/StateLeader。leader_host则直接给出当前领导者地址便于运维判断请求应发往哪个节点。space_stat按 IDC 聚合的物理空间统计disk_stat_infos数组与全局总量。disk_stat_infos中total是磁盘总数available/readonly/broken/repairing/repaired/dropping/dropped/expired分别对应各种磁盘状态的数量total_chunk与total_free_chunk是 chunk容量单元维度统计全局字段中total_space为物理总空间free_space为可写物理空间writable_space为可写逻辑空间total_blob_node为 BlobNode 节点数total_disk为磁盘总数。volume_stat卷状态统计total_volume为卷总数active_volume为活跃可服务读写卷数idle_volume为空闲卷数can_alloc_volume为可分配卷数lock_volume/unlocking_volume为锁定与解锁中的卷数。注意响应中的space_stat对应 blobstore 侧常说的 BlobNodeHDD空间而volume_stat中can_alloc_volume等字段来自卷分配器的实时统计。从实现上看blobstore/clustermgr/manage.go#L124-L137 中的Service.Stat依次聚合了 Raft 状态s.raftNode.Status()、Leader 地址、BlobNode 空间统计、ShardNode 空间统计、卷统计与集群只读标志其中卷统计由 blobstore/clustermgr/volumemgr/volumemgr.go#L545-L559 的VolumeMgr.Stat计算直接取自各卷状态的运行时计数。响应体结构的字段定义可对照 blobstore/api/clustermgr/disk.go 中的DiskStatInfo、SpaceStatInfo类型。三、节点管理节点管理面向 Raft 集群本身的成员变更包括添加节点、移除节点与切换领导者是 Clustermgr 扩缩容的核心操作。3.1 添加节点POST /member/add通过指定节点类型、地址与 ID 向 Raft 集群添加新成员curl -X POST --header Content-Type: application/json -d {peer_id: 1, host: 127.0.0.1:10110,node_host: 127.0.0.1:9998, member_type: 2} http://127.0.0.1:9998/member/add参数列表参数类型说明peer_iduint64Raft 节点 ID必须唯一hoststringRaft 地址节点间通信地址node_hoststring服务地址对外提供服务的地址member_typeuint8节点类型1 表示 leaner2 表示 normal其中member_type的取值在 blobstore/api/clustermgr/client.go 中定义为MemberType枚举MemberTypeLearner1学习者节点只同步日志不参与投票适合先追平数据再提升为正式成员与MemberTypeNormal2正式投票成员。请求体 JSON 字段与AddMemberArgs结构体一一对应type AddMemberArgs struct { PeerID uint64 json:peer_id Host string json:host MemberType MemberType json:member_type NodeHost string json:node_host }服务端 blobstore/clustermgr/manage.go#L40-L78 的MemberAdd处理逻辑值得注意首先校验member_type是否落在合法区间必须为 1 或 2否则返回参数非法遍历当前 Raftstatus.Peers若peer_id或host与已有成员重复直接返回ErrDuplicatedMemberInfo保证 ID 与地址的唯一性node_host会被序列化为MemberContext随成员信息一起持久化供后续路由使用最终调用s.raftNode.AddMember按类型分别以Learner: true/false加入。该接口没有独立参数表之外的可选字段一次请求完成一个节点的加入。3.2 移除节点POST /member/remove按 ID 从 Raft 集群中移除节点curl -X POST --header Content-Type: application/json -d {peer_id: 1} http://127.0.0.1:9998/member/remove参数列表参数类型说明peer_iduint64Raft 节点 ID必须唯一实现上blobstore/clustermgr/manage.go#L80-L104有两个关键约束先通过checkPeerIDExist校验节点确实存在不存在则返回参数非法不允许直接移除当前 Leader若peer_id等于当前raftNode.Status().Leader接口返回ErrRequestNotAllow。正确的扩缩容流程是先用/leadership/transfer把领导权转移给其他节点再执行移除。3.3 切换领导者POST /leadership/transfer按 ID 将 Raft 领导权转移到指定节点curl -X POST --header Content-Type: application/json -d {peer_id: 1} http://127.0.0.1:9998/leadership/transfer参数列表参数类型说明peer_iduint64Raft 节点 ID必须唯一对应实现 blobstore/clustermgr/manage.go#L106-L122 同样先校验节点存在再调用s.raftNode.TransferLeadership(ctx, s.raftNode.Status().Id, args.PeerID)完成领导权转移。注意该接口的peer_id是目标节点接收领导权的一方常用于 Leader 节点需要下线维护或触发重新选举的场景。四、磁盘管理磁盘管理围绕 BlobNode 上报的物理磁盘元数据展开支持查询、状态变更、读写属性切换与离线迁移。4.1 查询磁盘信息GET /disk/infocurl http://127.0.0.1:9998/disk/info?disk_id1参数列表参数类型说明disk_iduint32磁盘 ID响应示例{ cluster_id: 10001, create_time: 2022-05-07T15:22:01.62727140208:00, disk_id: 1, free: 1910475022336, free_chunk_cnt: 106, host: http://127.0.0.1:8889, idc: bjht, last_update_time: 2022-05-07T15:22:01.62727140208:00, max_chunk_cnt: 1037, path: /home/service/var/data21, rack: HT02-B11-F4-402-0203, readonly: false, size: 17828005326848, status: 1, used: 15917530304512, used_chunk_cnt: 931 }响应字段覆盖磁盘的归属信息cluster_id、idc、rack、host、path、容量信息size总容量、used/free已用与可用、max_chunk_cnt/used_chunk_cnt/free_chunk_cnt的 chunk 维度计数以及运行状态status磁盘状态、readonly是否只读、create_time/last_update_time。这些字段对应 blobstore/api/clustermgr/disk.go 中的BlobNodeDiskInfo结构体其中status的取值枚举定义在 blobstore/common/proto/const.go#L46-L51。4.2 设置磁盘状态POST /disk/setcurl -X POST --header Content-Type: application/json -d {disk_id:2,status:2} http://127.0.0.1:9998/disk/set参数类型说明disk_iduint32磁盘 IDstatusuint8磁盘状态只能递增数值含义见下表磁盘状态值说明1normal2broken3repairing4repaired5dropped状态枚举在 blobstore/common/proto/const.go#L46-L51 中定义DiskStatusNormal DiskStatus(iota 1) // 1 DiskStatusBroken // 2 DiskStatusRepairing // 3 DiskStatusRepaired // 4 DiskStatusDropped // 5 DiskStatusMax // 6服务端实现 blobstore/clustermgr/blobnode_disk.go#L152-L189 有几个细节需要运维人员注意该接口不允许设置 dropped5状态代码限定args.Status必须满足normal status dropped即只能设置 14磁盘离线dropped必须走专门的/disk/drop接口以保证数据迁移流程可控状态相同则直接返回不做重复写入当状态被设置为broken时会联动调用s.VolumeMgr.DiskWritableChange调整受影响卷的健康度让上层及时感知容量变化文档强调磁盘状态只能递增即运维应遵循 normal → broken → repairing → repaired 的推进顺序避免状态回退造成管理混乱。4.3 设置磁盘读写POST /disk/access将磁盘切换为只读或读写curl -X POST --header Content-Type: application/json -d {disk_id:2,readonly:false} http://127.0.0.1:9998/disk/access参数列表参数类型说明disk_iduint32磁盘 IDreadonlybool是否只读true 表示只读false 表示读写该接口与/disk/set互补/disk/set管理生命周期状态/disk/access管理读写权限。将磁盘置为只读常用于容量保护、异常排查或准备下线前的过渡只读状态下新数据不再写入该盘但存量数据仍可读取。4.4 设置磁盘下线POST /disk/drop针对机器或磁盘过保等场景可对磁盘执行下线以触发数据迁移。迁移过程中会先尝试直接读取离线磁盘上的数据若读取失败则走修复后读取流程保证数据尽量完整搬迁curl -X POST --header Content-Type: application/json -d {disk_id:2} http://127.0.0.1:9998/disk/drop服务端 blobstore/clustermgr/blobnode_disk.go#L191-L206 的DiskDrop仅接收disk_id随后交给s.BlobNodeMgr.DropDisk执行下线逻辑——它会将磁盘标记为 dropping由后台调度器接管数据迁移任务迁移期间可通过GET /disk/droppinglist查询进行中的下线列表相关路由见 blobstore/clustermgr/handler.go。注意/disk/drop是异步触发的接口返回只代表下线任务已受理实际迁移进度由后台任务系统持续推进。五、卷管理GET /volume/get查询单个卷的详细信息包括卷的编码模式、容量使用与构成该卷的所有存储单元curl http://127.0.0.1:9998/volume/get?vid1参数列表参数类型说明viduint32卷 ID响应示例{ code_mode: 12, create_by_node_id: 1, free: 1061027840, health_score: 0, status: 1, total: 171798691840, units: [ { disk_id: 112, host: http://127.0.0.1:8889, vuid: 4294967654 }, ... { disk_id: 401, host: http://127.0.0.1:8889, vuid: 4513071462 } ], used: 170737664000, vid: 1 }字段含义code_mode卷的纠删码编码模式编号如 12 对应某种 EC 冗余策略编码模式定义见 blobstore/common/codemode 目录它决定了units中存储单元的数量与冗余配比vid/status卷 ID 与卷状态total/used/free卷的逻辑容量、已用与可用空间units构成该卷的底层存储单元列表每个单元由vuidVolume Unit ID、disk_id和所在 BlobNode 的host唯一标识这也是卷路由Volume Route的基础数据health_score卷健康分反映底层单元异常情况数值越大通常意味着可用性越差。对应的请求与响应结构定义在 blobstore/api/clustermgr/volume.goGetVolumeArgs只含vid响应VolumeInfo由Units []Unit与VolumeInfoBase组合而成其中Unit结构体为{Vuid, DiskID, Host}三元组。六、后台任务开关管理Clustermgr 会把磁盘修复、数据均衡、磁盘离线、数据删除、数据修复、数据巡检等后台任务的启停状态保存在自身的 KV 配置中运维可随时查询与切换。支持的六类任务如下任务类型type任务名称key开关valueDisk Repairdisk_repairtrue/falseData Balancingbalancetrue/falseDisk Offlinedisk_droptrue/falseData Deletionblob_deletetrue/falseData Repairshard_repairtrue/falseData Inspectionvolume_inspecttrue/false这些任务名与 blobstore/common/proto/scheduler.go#L40-L46 中定义的TaskType常量一一对应disk_repair、balance、disk_drop、volume_inspect、shard_repair、blob_delete调度器与 CLI 工具均以这些字符串作为开关的 key。6.1 查看任务状态curl http://127.0.0.1:9998/config/get?keybalance # 或使用 blobstore-cli blobstore-cli cm background status balance6.2 开启任务curl -X POST http://127.0.0.1:9998/config/set -d {key:balance,value:true} --header Content-Type: application/json # 或使用 blobstore-cli blobstore-cli cm background enable balance6.3 关闭任务curl -X POST http://127.0.0.1:9998/config/set -d {key:balance,value:false} --header Content-Type: application/json # 或使用 blobstore-cli blobstore-cli cm background disable balance背后的实现机制在 blobstore/clustermgr/config.go 中非常清晰ConfigGetL32-L59属于线性一致读先调用s.raftNode.ReadIndex(ctx)确认当前节点状态已追平 Leader 的提交水位再从ConfigMgr读取配置保证读到的一定是最新值ConfigSetL61-L90走Raft Propose 持久化将{key, value}序列化后封装为OperTypeSetConfig提案提交给 Raft经多数派确认后才生效因此任何节点发起的配置变更都会在集群内保持一致同时若 key 属于proto.IsUnmodifiableSysConfigKey保护的系统配置接口会直接拒绝防止误改核心配置。6.4 blobstore-cli 用法补充blobstore-cli cm background子命令定义在 blobstore/cli/clustermgr/background.go支持status、enable、disable三个动作交互式确认后执行适合人工操作其底层仍是通过上述config/get与config/set接口完成读写并在enable/disable时校验任务名合法性。除后台任务外blobstore-cli cm还提供磁盘管理、卷管理等更多子命令见 blobstore/cli/clustermgr 目录例如blobstore-cli cm disk set、blobstore-cli cm volume get等可作为 curl 之外的另一条运维路径。七、运维要点小结结合文档与源码使用 Clustermgr 管理 API 时有几个值得牢记的实践要点写操作务必发往 Leader/member/add、/disk/set、/config/set等写接口依赖 Raft Propose若请求落在 Follower 上会因无法提交而失败。日常可通过GET /stat的leader_host字段定位当前 Leader将管理请求定向发送。移除节点前先转移领导权/member/remove明确禁止移除 Leader标准流程是/leadership/transfer转移后再执行移除避免集群在无主状态下操作。磁盘状态单向推进/disk/set只能设置 normal→broken→repairing→repaired 序列且不能直接置为 dropped真正的下线操作必须走/disk/drop由后台调度器完成数据迁移。后台任务开关全局生效且持久化任务开关以true/false字符串存储在 Raft 共识的配置中任意节点写入、全集群一致适合在维护窗口统一关闭均衡、巡检等任务以减少干扰。以上接口的路由、参数解析与实现均可对照仓库源码进一步学习路由全表见 blobstore/clustermgr/handler.go节点管理实现在 blobstore/clustermgr/manage.go磁盘管理实现在 blobstore/clustermgr/blobnode_disk.go配置管理实现在 blobstore/clustermgr/config.goGo 客户端封装见 blobstore/api/clustermgr/client.go 及同目录下的disk.go、volume.go、config.go。赞分享存储分布式文件系统对象存储云原生【免费下载链接】cubefscloud-native distributed storage项目地址https://gitcode.com/gh_mirrors/cu/cubefs点击查看免费下载相关推荐CubeFS BlobStore Clustermgr 管理 API 实战指南节点、磁盘、卷与后台任务运维CubeFS BlobStore Clustermgr 管理 API 实战指南节点、磁盘、卷与后台任务运维 Clustermgr 是 CubeFS BlobS存储分布式文件系统对象存储云原生本地 RAG 实战指南Genkit 加 Ollama5 分钟搭起宝可梦问答应用本地 RAG 实战指南Genkit 加 Ollama5 分钟搭起宝可梦问答应用 想让数据不出本机也能做知识库问答Genkit 的 js/testapps/存储分布式文件系统对象存储云原生CubeFS Blobstore Scheduler 后台任务管理实战指南状态查询、手动迁移与任务详情排查CubeFS Blobstore Scheduler 后台任务管理实战指南状态查询、手动迁移与任务详情排查 CubeFS 的 Blobstore 存储子系统通存储分布式文件系统对象存储云原生上一篇ICR - 交互式Crystal编程语言控制台下一篇TSDF-Fusion 项目推荐创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考