☰
Apache Mesos 多磁盘(Multiple Disks)资源配置与实现深度指南
2026/10/13 3:04:59 网站建设 项目流程
  • 集群管理
  • 任务调度
  • 后端

【免费下载链接】mesos

Apache Mesos

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

本文以 Apache Mesos 的 Multiple Disks 机制为核心,系统讲解 Root、Path、Mount 三类磁盘资源的概念、JSON 配置方法与底层实现原理,帮助集群运维人员正确地在 Agent 启动时暴露多块磁盘,并让框架(Framework)在创建持久卷时根据DiskInfo.source精确选择存储介质。读完本文,你将掌握--resources参数的手工编写规范、三类磁盘的适用场景与限制,以及 Mesos 在卷路径映射、销毁清理和磁盘配额隔离上的真实行为。

为什么需要多磁盘支持

在 Mesos 集群中,磁盘(disk)是 Agent 上报的标量资源之一。默认情况下,Agent 只把操作系统主盘暴露给集群,所有任务数据都落在 Agent 的work_dir里。但在生产环境中,日志、数据库、写前日志(WAL)、缓存等负载对存储介质的要求截然不同,因此 Mesos 提供了一种机制,让运维人员可以把多块磁盘以不同形态暴露给集群。

当框架通过acceptOffers响应资源 Offer 并执行Offer::Operation::Create创建持久卷时,可以检查磁盘资源的source字段来决定是否使用某块特定磁盘。也就是说,source是框架区分“普通根盘”与“指定数据盘”的唯一依据。

三类磁盘资源

在 include/mesos/mesos.proto 中,Resource.DiskInfo定义了可选的Source子消息,其Type枚举为:

UNKNOWN = 0 PATH = 1 MOUNT = 2 BLOCK = 3 RAW = 4

对应地,Mesos 的磁盘资源以三种形态呈现:

1.Root磁盘(根盘)

Root磁盘是 Mesos 中最基本的磁盘资源,表现为DiskInfo中不设置source。它通常映射到运维人员提供给 Agent 的操作系统主盘存储,数据被映射进 Agent 的work_dir(即--work_dir指定的目录)。默认情况下(未指定--resources时),Mesos Agent 只会向集群暴露这块根盘。

在源码中,未带source的持久卷会被直接映射到工作目录下,见 src/slave/paths.cpp:

// If no `source` is provided in `DiskInfo` volumes are mapped into // the `workDir`. if (!volume.disk().has_source()) { return getPersistentVolumePath( workDir, role, volume.disk().persistence().id()); }

2.Path磁盘

Path磁盘是运维人员提供的辅助磁盘资源,表现为DiskInfo.source.type设为PATH,并通过source.path.root指定用于存储数据的目录。它可以被框架切割成更小的块——框架可以在同一块 Path 磁盘上创建多个占用量小于总空间的持久卷。

常见的适用场景包括:额外的日志空间、文件归档或缓存、以及其他对性能不敏感的应用。运维人员只需创建一个目录,并把该目录设为Path的root,即可把一块磁盘以Path形态暴露出来。

Path磁盘还非常适合在测试或预发环境模拟多磁盘环境——直接在操作系统盘上创建几个目录即可,无需真实物理盘。但要注意:在同一文件系统上创建多个Path磁盘,等于静态地瓜分了磁盘容量。例如,10GB 存储设备挂载到/foo,若配置两个 Path 盘/foo/disk1与/foo/disk2,则 Agent 启动时这两块盘的总配置容量不应超过 10GB,否则存在磁盘写满的风险。

3.Mount磁盘

Mount磁盘同样是辅助磁盘资源,但表现为DiskInfo.source.type设为MOUNT,通过source.mount.root指定挂载点。与Path磁盘相反,它不能被框架切割——框架无法只取该盘的一部分,这种“非灵活性”反而让运维人员可以向框架保证:拿到这块盘的框架将独占整个磁盘设备。

常见适用场景包括:数据库存储、写前日志、以及其他性能敏感的负载。在 Linux 上,Mount磁盘必须对应/proc/mounts挂载表中的真实挂载点:运维人员先以首选文件系统挂载物理磁盘,再把挂载点作为Mount的root提交给 Agent。

除了性能优势,运行在Mount磁盘上的应用还能依赖“写满时报磁盘错误”的行为(只要所用文件系统能正确向上层传播这些错误)。正因如此,Mesos 对Mount磁盘关闭了disk/du隔离——配额由底层文件系统天然保证,无需 Mesos 再用du统计(见下文“配额与隔离”)。

Block磁盘(当前不支持)

Mesos 目前不允许运维人员直接暴露裸块设备(raw block devices)。虽然Source.Type枚举中已预留BLOCK与RAW,但该能力可能在未来引入,前提是先以设计文档解决安全与灵活性方面的顾虑。在 src/slave/slave.cpp 中,Agent 启动校验会对BLOCK、RAW、UNKNOWN直接报错退出:

case Resource::DiskInfo::Source::BLOCK: case Resource::DiskInfo::Source::RAW: case Resource::DiskInfo::Source::UNKNOWN: { EXIT(EXIT_FAILURE) << "Unsupported 'DiskInfo.Source.Type' in '" << resource << "'"; }

通过--resources配置多磁盘

运维人员在 Agent 启动时,通过 JSON 格式的--resources参数提供这些不同形态的磁盘资源。需要特别强调的是:

注意:一旦你通过--resources手工指定了任何disk资源,Mesos 将停止自动探测Root磁盘。因此若还想使用根盘,必须按下面描述的格式手工将其一并写入--resources。

这一行为的根源在 src/slave/containerizer/containerizer.cpp:Containerizer::resources会解析--resources,逐项检查是否显式包含cpus、mem、disk、ports;只有未显式给出的项才会触发系统自动探测。对disk而言,自动探测逻辑是取--work_dir所在文件系统的容量(fs::size(flags.work_dir))。

Root磁盘的 JSON 示例

不设置source即为根盘,其中scalar.value的单位为 MB,2048表示 2GB。运维人员还可以可选地为磁盘指定role字段,从而把磁盘静态预留(statically reserving)给单一角色(role):

[ { "name" : "disk", "type" : "SCALAR", "scalar" : { "value" : 2048 } } ]

Path磁盘的 JSON 示例

source.type设为PATH,source.path.root设为存储根目录。同样可选用role字段实现静态预留:

[ { "name" : "disk", "type" : "SCALAR", "scalar" : { "value" : 2048 }, "disk" : { "source" : { "type" : "PATH", "path" : { "root" : "/mnt/data" } } } } ]

Mount磁盘的 JSON 示例

source.type设为MOUNT,source.mount.root必须是一个真实挂载点(Linux 下须存在于/proc/mounts):

[ { "name" : "disk", "type" : "SCALAR", "scalar" : { "value" : 2048 }, "disk" : { "source" : { "type" : "MOUNT", "mount" : { "root" : "/mnt/data" } } } } ]

root路径的取值规则

根据 include/mesos/mesos.proto 的注释,无论是Path.root还是Mount.root:

  • 若为绝对路径(如/mnt/raid/disk0),直接使用;
  • 若为相对路径,则相对于 Agent 的work_dir解析。

这一规则在 src/slave/paths.cpp 中得到印证:

if (!path::is_absolute(root)) { // A relative path in `root` is relative to agent work dir. root = path::join(workDir, root); }

Agent 启动时的磁盘校验

在 src/slave/slave.cpp 中,Agent 初始化时会遍历所有带source的磁盘资源并逐一验证其可访问性,任何一项失败都会导致 Agent 启动失败退出:

  • PATH磁盘:要求source.path及其root必须存在,否则报错;若目录尚不存在,Agent 会主动创建(os::mkdir(source.path().root(), true),true表示递归创建父目录)。这意味着运维人员可以预先写好配置,目录由 Agent 自动补建。
  • MOUNT磁盘:要求source.mount及其root必须存在。在 Linux 上,Agent 会先对root做realpath解析,再读取/proc/mounts挂载表(fs::MountTable::read)逐条比对,只有realpath与某个挂载条目目录完全一致才通过;非 Linux 平台则只检查路径是否存在。

此外,Agent 还把校验后的资源写入SlaveInfo并向 Master 注册(info.mutable_resources()->CopyFrom(resources.get()),见 src/slave/slave.cpp)。

持久卷的底层实现差异

Path与Mount磁盘在持久卷的路径组织与销毁语义上存在根本区别,运维人员在检查或清理残余数据时必须留意。

卷路径映射

在 src/slave/paths.cpp 中,持久卷的路径按source类型映射:

  • PATH:Mesos 会在root内创建子目录来区分其上创建的各个卷,卷路径为getPersistentVolumePath(root, role, persistence.id()),即“根目录 + 角色 + 卷 ID”的组合目录。
  • MOUNT:卷直接映射到root(挂载点本身),不会创建子目录,应用可以使用该设备上完整且预先存在的目录结构。

正是这种设计,让 Mesos 任务可以直接访问包含既有数据的卷——例如导入一个已存在的 PostgreSQL 数据目录或 HDFS 数据目录时,无需复制数据即可直接使用。

销毁语义

在 src/slave/slave.cpp 中,Slave销毁持久卷时的行为由source.type决定:

bool removeRoot = true; if (source.type() == Resource::DiskInfo::Source::MOUNT) { removeRoot = false; } Try<Nothing> result = os::rmdir(path, true, removeRoot);
  • 销毁Path卷时,Mesos 会删除卷中存储的所有文件与目录,连同Mesos 在root下为该卷创建的子目录一起删除(removeRoot = true)。
  • 销毁Mount卷时,Mesos 会删除卷中存储的所有文件与目录,但不会删除根目录(即挂载点本身,removeRoot = false)。

因此,在人工清理残余数据时:Path 盘上遗留的卷子目录可以安全删除;而 Mount 盘上的挂载点必须保留,只能清理其中的内容。

配额与disk/du隔离

disk/du是 Mesos 的 POSIX 磁盘隔离器(实现于 src/slave/containerizer/mesos/isolators/posix/disk.cpp,注册名映射见 src/slave/containerizer/mesos/containerizer.cpp),负责统计容器磁盘用量并执行配额限制。

在 src/slave/containerizer/mesos/isolators/posix/disk.cpp 中,配额强制逻辑会显式跳过MOUNT类型的磁盘资源:

// We need to ignore the quota enforcement check for MOUNT type // disk resources because its quota will be enforced by the // underlying filesystem. bool isDiskSourceMount = false; foreach (const Resource& resource, info->paths[path].quota) { if (resource.has_disk() && resource.disk().has_source() && resource.disk().source().type() == Resource::DiskInfo::Source::MOUNT) { isDiskSourceMount = true; } } if (!isDiskSourceMount) { ... }

也就是说,Path卷的配额由 Mesos 用du统计并强制执行,而Mount卷的容量约束交给底层文件系统(应用写满时会收到磁盘错误)。XFS 磁盘隔离器(src/slave/containerizer/mesos/isolators/xfs/disk.cpp)也通过同样的isMountDisk判断对MOUNT磁盘采取不同处理。

实战建议与注意事项

综合文档与源码,给运维人员如下操作要点:

  1. 手工指定即全量指定:一旦--resources中出现任何disk条目,Agent 就不再自动探测根盘;根盘、Path 盘、Mount 盘必须一次全部写全。
  2. Path 盘注意总容量:同一文件系统上的多个 Path 盘,配置容量之和不得超过设备真实容量,避免静态分区导致磁盘写满。
  3. Mount 盘必须真实挂载:Linux 下source.mount.root必须是/proc/mounts中的真实挂载点(Agent 启动时校验,realpath后逐条比对),不能只是一个普通目录。
  4. Mount 盘适合有状态高性能负载:独占设备、无子目录、配额由文件系统保证、可访问预置数据目录,是数据库与 WAL 的首选;Path 盘则适合日志、缓存等可切割场景。
  5. 清理残余数据看类型:Path 卷销毁后其卷子目录一并消失;Mount 卷销毁后挂载点仍保留,只能手动清理其中的文件,切勿删除挂载点本身。
  6. 权限控制:卷的创建与销毁受到授权(authorization)机制的约束,框架与运维人员操作时需提供principal;结合预留(reservation)与角色(roles)可实现对特定磁盘的静态预留。

延伸阅读

  • 持久卷 Persistent Volumes:如何在Path/Mount磁盘上创建持久卷
  • 预留 Reservation:磁盘资源的静态与动态预留机制
  • 角色 Roles:资源与角色绑定关系
  • 共享资源 Shared Resources:可被多个任务同时访问的共享持久卷
  • 授权 Authorization:卷创建/销毁的 ACL 控制
  • 集群管理
  • 任务调度
  • 后端

【免费下载链接】mesos

Apache Mesos

项目地址:https://gitcode.com/gh_mirrors/mesos1/mesos
点击查看免费下载
上一篇:Apache Arrow Acero 流式执行引擎(Streaming Execution Engine)C++ 使用指南
下一篇:基于 Claude 与 Next.js 构建金融数据分析助手:financial-data-analyst 全流程实战指南

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

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

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

立即咨询