想象你是云上企业的后勤主管,手头有一栋「数字公寓楼」——服务器集群。每天有无数「租客」入住:有的像出差旅客,今晚住明早走(批处理任务);有的像常年住户,盼着拎包入住、全天不断电(在线服务)。谁来分配房间?房间长什么样?谁保证服务不中断?这正是资源调度系统要做的事。 业内有三套主流「分房方案」:YARN 像老式招待所前台,坐在柜台后统一派钥匙;Mesos 像物业经理,只告诉你「有几间空房」,你自己决定怎么布置;K8s 则像智能公寓管家,你只要说「要一间带阳台的套房」,剩下的事它持续替你打理。三套方案没有绝对的好坏,只有合不合适。本文就用这场「找房入住」的故事,带你横向拆解三者的架构、调度策略、资源模型与高可用方案,最后给出选型决策的完整框架。

岗位关联

对所有 AI 从业者而言,调度系统是数据平台与云原生基础设施的「心脏」。理解 YARN/Mesos/K8s 的差异,能让你在搭建训练平台、推理集群或大数据链路时少走弯路,从「被运维牵着走」升级为「主导架构选型」。

目录
  1. 可视化演示
  2. 架构设计:三位「公寓管家」的组成方式
  3. 调度策略:分房决策的「内部算法」
  4. 资源模型:三种「房间规格」
  5. 高可用方案:管家请假了怎么办?
  6. 工作负载适配:哪种租客住哪种楼?
  7. 选型决策:如何给你的集群选「管家」?
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

展示三大调度系统架构差异、调度策略雷达对比及工作负载适配曲线,直观呈现集中式/两级/声明式调度选型决策。

本节配有交互动效(进入视口后自动加载,约 3KB)。

三大调度系统架构 YARN:集中式调度,层级队列容量分配 Mesos:两级调度,资源邀约机制 选型=负载×生态×规模 K8s声明式编排

架构设计:三位「公寓管家」的组成方式

把 YARN 想象成老式招待所:大堂里坐着唯一的接待员(ResourceManager),每层楼有一位值班保洁(NodeManager)。你入住时,接待员给你一把钥匙,告诉你「去 3 层 302 房间」,房间是固定的标准间,里面只有床和桌子——这就是一个 Container(容器)。招待所的优势是流程简单、权责清晰;缺点是接待员只有一位,住客一多,前台就成了瓶颈。

Mesos 则是另一种经营哲学:物业经理(Mesos master)不要亲自带客人去房间,他只站在大厅里喊一句:「302 空出来了,谁要?」——这句话就是一个资源 Offer。想入驻的租户(framework,比如 Spark 或 Marathon)听到后,自己决定要不要、怎么改造这间房。这就是双层调度:第一层是物业经理分配 Offer,第二层是租户在 Offer 范围内自由布置。好处是灵活性高、多种租户能共享同一栋楼,坏处是没人全局统一规划,容易产生「房间零碎、大客户没法住」的资源碎片。

K8s 的智能公寓模式最「懒人友好」。你不需要知道房间在哪、由谁打扫,你只在前台系统(kube-apiserver)提交一句话:「我要 3 间带独立卫浴的套房」,智能管家(各类 controller)就开始工作。管家每隔几秒巡视一圈(reconcile loop):现在有 2 间,缺 1 间,就立刻补上;多出来就收回。这种「声明式」架构让运维从「天天盯着房间状态」变成「只管提需求」。

1. 符号定义:任务 j 的需求用 \(d_j^{cpu}\) 和 \(d_j^{mem}\) 表示,节点 i 的可用资源为 \(r_i^{cpu}\) 和 \(r_i^{mem}\)。

dj=(djcpu,djmem),ri=(ricpu,rimem)\displaystyle d_j = (d_j^{cpu}, d_j^{mem}), \quad r_i = (r_i^{cpu}, r_i^{mem})

2. CPU 判断:节点剩余 CPU 必须不少于任务申请量,否则任务会「挤爆」CPU。

ricpu≥djcpu\displaystyle r_i^{cpu} \geq d_j^{cpu}

3. 内存判断:节点剩余内存也必须足够,防止触发 OOM。

rimem≥djmem\displaystyle r_i^{mem} \geq d_j^{mem}

4. 逻辑与连接:两者必须同时成立,调度器才会把任务放到该节点上。

(条件A)∧(条件B)\displaystyle (\text{条件A}) \land (\text{条件B})

「招待所前台、物业经理、智能管家」——三种架构没有谁完美。前台的瓶颈在单点,物业的难题在碎片,管家的复杂度则在控制面组件众多。选哪个,取决于你的租客到底需要什么样的服务。

text1 行
\displaystyle \text{canSchedule}(j,i) = \left( r_i^{cpu} \geq d_j^{cpu} \right) \land \left( r_i^{mem} \geq d_j^{mem} \right)

调度策略:分房决策的「内部算法」

招待所怎么分房?YARN 提供了三种「队形」:FIFO 先到先得,新任务只能排在后面;Capacity 调度器则像楼层分区,每层楼有固定配额,不能挤占其他楼层;Fair 调度器像公交车的「按需发车」,所有任务按权重动态瓜分资源,饥饿任务会优先补量。

Mesos 的分房更像「撮合交易」。物业经理把空闲房间打包成 Offer 推给各个租户,租户如果嫌房间太小,可以说「不要」,等下一波 Offer。这个机制天然支持多租户共享,但注意:Offer 里的资源是对框架「可见但未锁定」的,只在租户确认接受后才真正分配。

K8s 的调度器则像相亲节目中的「双轮筛选」:第一轮过滤(predicate)把不满足硬性条件的候选人淘汰——比如内存不够、端口冲突;第二轮打分(priority)给剩下的人按软性偏好排序——比如资源余量越多分越高、离指定机柜越近加分。最终得分最高的节点胜出。

回看三种「分房算法」:YARN 的队列是刚性约束,Mesos 的 Offer 是自愿交易,K8s 的打分是全局择优。分房策略决定了集群的公平性、吞吐率和响应速度,是调度器最核心的「性格」。

s^i=R⋅wi∑j=1nwj\displaystyle \widehat{s}_i = \frac{R \cdot w_i}{\sum_{j=1}^{n} w_j}
这是带权重的公平分配公式:第 i 个队列应获得的资源量等于集群总资源乘以它的权重占总权重的比例。
  1. 权重定义每个任务或队列拥有权重 \(w_i\),权重大的「该分得多」。
    wi=队列/任务的优先级权重\displaystyle w_i = \text{队列/任务的优先级权重}
  2. 总资源乘以比例集群总资源 \(R\) 乘以该队列权重占全体权重之和的比例,得到理论份额。
    R⋅wi∑j=1nwj\displaystyle R \cdot \frac{w_i}{\sum_{j=1}^{n} w_j}
  3. 结果解释若所有队列权重相同,则份额退化为平均分配;权重不同则资源向高权重倾斜。
    s^i∝wi\displaystyle \widehat{s}_i \propto w_i

资源模型:三种「房间规格」

YARN 的房间规格是「标准间」:一个 Container 由内存 + CPU 两种资源量定义,比如「2 核 4G」。这是对物理机资源的粗粒度抽象,优点是简单、好统计,缺点是无法精细化描述 GPU、延迟等特殊资源。

Mesos 的房间是「毛坯房」:物业经理报出的 Offer 是「这间房剩余 8 核 16G,毛坯交付」,租户拿走后自己决定装修成什么。Offer 本质上是一组资源的快照,框架可以组合多个 Offer 来满足一个大任务。

K8s 的房间则是「精装 Loft」:Pod 是最小调度单元,里面可以包含多个容器,共享网络和存储。每个 Pod 申请资源时用 requests 表明「保底需求」,用 limits 设置「最高用水量」,这就像入住时告诉管家:「空调得开 26 度(requests),但最高别超过 30 度(limits)」,超过 limits 就会被管家强行关掉。

从「标准间」到「毛坯房」再到「精装 Loft」,资源模型越来越丰富、语义越来越强。K8s 之所以统治云原生,正是因为它把「房间」定义得足够精细,让调度器能做出更聪明的决策。

v=(ccores,  mmem,  ggpu)\displaystyle v = (c_{\text{cores}},\; m_{\text{mem}},\; g_{\text{gpu}})
三种调度器都把资源抽象成多维向量:CPU 核数、内存大小、GPU 卡数。
  1. 向量建模把一台机器的资源描述为一个多维向量,每维对应一种资源。
    v∈R3,v1=ccores\displaystyle v \in \mathbb{R}^{3}, \quad v_1 = c_{cores}
  2. CPU 维度核数决定任务可获得的并行计算能力。
    ccores=申请的CPU核数\displaystyle c_{\text{cores}} = \text{申请的CPU核数}
  3. 内存与 GPU 维度内存决定数据装载上限,GPU 数量决定是否满足 AI 训练需求。
    mmem  (GB),ggpu  (卡)\displaystyle m_{\text{mem}} \; \text{(GB)}, \quad g_{\text{gpu}} \; \text{(卡)}

高可用方案:管家请假了怎么办?

招待所前台累倒了怎么办?YARN 的做法是配备双前台:Active 与 Standby 两个 ResourceManager 通过 ZooKeeper 选主,主节点挂了,备节点几秒内顶上。注意:切换期间正在运行的任务会「暂时失联」,但已提交的作业能恢复。

Mesos 物业经理也采用类似机制:多台 master 通过 ZooKeeper 选出领导者,其余作为备份。但 Mesos master 属于「有状态」角色,切换时正在协商的 Offer 可能丢失,需要框架重试。

K8s 的智能公寓管理得更彻底:整个控制平面近乎无状态。真正存数据的是分布式数据库 etcd,用 Raft 协议保证多副本一致——就像把住户档案分了三份存进三个保险柜,只要多数保险柜在,档案就不会丢。控制面各组件都是多副本,挂掉一个,负载均衡自动把请求转到另一个。

三种高可用方案最终比拼的是「故障转移速度」和「数据不丢」两个指标。前台换人最快 10 秒,物业换人可能要重谈 Offer,而智能管家因为档案都在 etcd 且同步复制,做到了「换人不换账」。

A=MTBFMTBF+MTTR\displaystyle A = \frac{MTBF}{MTBF + MTTR}
系统可用性 = 平均无故障时间除以(平均无故障时间 + 平均修复时间)。想让可用性趋近 100%,要么让系统少坏,要么让坏的时间极短。
  1. MTBF 定义平均无故障时间,即系统连续正常运行的平均时长。
    MTBF=运行总时长故障次数\displaystyle MTBF = \frac{\text{运行总时长}}{\text{故障次数}}
  2. MTTR 定义平均修复时间,即从故障发生到恢复的平均耗时。
    MTTR=修复总耗时故障次数\displaystyle MTTR = \frac{\text{修复总耗时}}{\text{故障次数}}
  3. 代入求值分子分母同除 MTBF,可用性由修复时间占比决定。
    A=11+MTTRMTBF\displaystyle A = \frac{1}{1 + \frac{MTTR}{MTBF}}

工作负载适配:哪种租客住哪种楼?

YARN 这座招待所最擅长接待「短期旅客」——MapReduce、Spark、Flink 这类批处理与流计算任务。这类任务生命周期短、资源需求明确,正符合前台统一分发、快速入住的模式。现实中,阿里、腾讯等大厂的大数据平台大量跑在 YARN 上。

Mesos 这种「物业 + 毛坯房」的模式非常适合「混合社区」:一边住着 Marathon 管理的常驻服务(长时运行,像小卖部),一边住着临时摆摊的批处理任务。当集群同时存在在线服务和离线批处理,Mesos 的 Offer 撮合机制能灵活协调。

K8s 则是「全能公寓」。Deployment 管无状态服务(像酒店客房),StatefulSet 管有状态服务(像固定包年的主力店,有固定门牌号和专属储物柜),Job 管一次性任务(像临时会议室)。AI 圈最火的方案——KubeFlow、Ray on K8s——都是把训练和推理任务塞进 K8s,实现自动扩容、自动恢复。

租客决定楼的选择。如果你的主业是大数据离线计算,YARN 的生态成熟度无可替代;如果机器上既要跑 Web 服务又要跑定时任务,Mesos 的混合调度有独到优势;如果你拥抱云原生,希望训练、推理、微服务统一管理,K8s 是既定未来。

Emix=Ubatch+UonlineRtotal\displaystyle E_{\text{mix}} = \frac{U_{\text{batch}} + U_{\text{online}}}{R_{\text{total}}}
混合部署效率 = 离线任务利用率与在线任务利用率之和 ÷ 集群总资源,衡量「一栋楼同时住两类租客」的省钱效果。
  1. 利用率定义各类任务实际使用的资源总和。
    Ubatch+Uonline\displaystyle U_{\text{batch}} + U_{\text{online}}
  2. 总资源归一除以集群全部资源,得到整体资源利用效率。
    Rtotal=∑iri\displaystyle R_{\text{total}} = \sum_{i} r_i
  3. 混部收益若两类任务错峰使用资源,叠加利用率可超过 60%,远高于单类负载。
    Emix>max⁡(Ubatch,Uonline)\displaystyle E_{\text{mix}} > \max(U_{\text{batch}}, U_{\text{online}})

选型决策:如何给你的集群选「管家」?

选型不是比参数,而是比「生态」和「场景」。YARN 背后是 Hadoop 全家桶,离线数仓、Spark SQL、Flink 都深度集成,数据工程师上手成本最低;缺点是与云原生生态割裂,想跑容器化微服务需要额外框架集成。

Mesos 的生态相对尴尬:Apache Mesos 社区近年活力下降,Marathon 的功能被 K8s 快速追赶。但它启发了很多现代调度器,理解它对理解双层调度思想很有价值。不建议新项目从零选 Mesos,除非是存量系统维护。

K8s 是当前最确定的增量方向。几乎所有云厂商都提供托管的 Kubernetes 服务,从在线推理到离线训练,从 Spark 到 Flink,都能在 K8s 上找到入口。代价是学习曲线陡峭,控制面组件多,对运维要求高。

选「管家」的最终建议是:存量大数据平台维持 YARN,新项目优先 K8s,Mesos 只在历史系统中尊重它。三者的「简历」都很漂亮,但你要招的是最懂你团队场景的那个人。

Tscore=∑k=1mwk⋅sk\displaystyle T_{\text{score}} = \sum_{k=1}^{m} w_k \cdot s_k
加权评分法:把生态成熟度、运维复杂度、云原生趋势等 KPI 分别打分,乘以权重后求和,用总分辅助决策。
  1. 维度枚举定义 m 个评估维度,如生态、运维、性能、成本。
    k=1,2,…,m\displaystyle k = 1, 2, \ldots, m
  2. 权重赋值每个维度乘以权重 \(w_k\),代表你对这个维度的重视程度。
    sk⋅wk\displaystyle s_k \cdot w_k
  3. 总和对比对每个候选系统求总分 \(T_{\text{score}}\),选分最高者。
    Tscore(YARN),Tscore(Mesos),Tscore(K8s)\displaystyle T_{\text{score}}^{(YARN)}, \quad T_{\text{score}}^{(Mesos)}, \quad T_{\text{score}}^{(K8s)}

AI 应用场景

场景 1:互联网大厂的离线数仓平台

阶段:数据基础设施 / 训练数据准备

解决的问题:每日万亿级日志清洗、特征工程需要上千台机器同时跑 Spark 任务,传统手工拆任务毫无可操作性。用 YARN 做资源调度,数据工程师只需提交作业,ResourceManager 自动排队、分配 Container、释放资源。

具体案例:某电商平台每日凌晨启动 5000 个 Spark 任务,YARN 的 Fair Scheduler 按部门权重分配资源,重要部门的实时特征任务优先获得资源,离线训练任务自动让路。

场景 2:混合负载统一调度平台

阶段:模型训练与在线推理共存

解决的问题:训练任务需要大量 GPU 短时占用,而在线推理服务需要长期稳定的资源。如果两套集群分开跑,资源利用率很低;Mesos 的 Offer 机制可以在同一集群上同时跑 Marathon 长时服务和短时训练任务。

具体案例:某中型公司的 GPU 集群高峰期 60% 被在线推理占用,剩余碎片时段被训练任务使用,Mesos 将整体利用率从 35% 提升到 55%。

场景 3:云原生 AI 推理平台

阶段:模型部署与弹性伸缩

解决的问题:模型推理流量波动大,高峰期每秒上千次请求,低峰期几乎闲置。K8s 的声明式控制器可以按 HPA 指标自动扩缩 Pod,还能在 GPU 节点故障时自动迁移模型副本。

具体案例:某 AI 公司把用户画像模型部署到 K8s,配置 Pod 数为 30、CPU 利用率阈值 60%,双十一流量涨到 5 倍时,系统在 2 分钟内自动扩容到 120 个副本,流量回落后自动缩容,账单成本下降 40%。

Python 演示

python116 行
# -*- coding: utf-8 -*-"""三种调度器的最小模拟:YARN 集中 / Mesos 双层 / K8s 声明式"""class ResourceNode(object):    """一个计算节点,有 CPU 和内存资源"""    def __init__(self, name, cpu_total, mem_total):        self.name = name        self.cpu_total = cpu_total        self.mem_total = mem_total        self.tasks = []     def available(self):        """当前剩余资源"""        used_cpu = sum(t['cpu'] for t in self.tasks)        used_mem = sum(t['mem'] for t in self.tasks)        return {'cpu': self.cpu_total - used_cpu,                'mem': self.mem_total - used_mem}     def add_task(self, task):        """放置任务并返回是否成功"""        av = self.available()        if task['cpu'] <= av['cpu'] and task['mem'] <= av['mem']:            self.tasks.append(task)            return True        return False  class YARNScheduler(object):    """YARN 集中式调度:任务进队列,全局统一分配"""    def __init__(self, nodes):        self.nodes = nodes        self.queue = []     def submit(self, task):        self.queue.append(task)     def schedule(self):        rest = []        for task in self.queue:            placed = False            for node in self.nodes:                if node.add_task(task):                    placed = True                    break            if not placed:                rest.append(task)        self.queue = rest  class MesosScheduler(object):    """Mesos 双层调度:节点发 Offer,框架自主选择"""    def __init__(self, nodes):        self.nodes = nodes     def get_offers(self):        offers = []        for i, node in enumerate(self.nodes):            av = node.available()            if av['cpu'] > 0 and av['mem'] > 0:                offers.append((i, av))        return offers     def schedule(self, tasks):        offers = self.get_offers()        for task in tasks:            while offers:                node_idx, av = offers.pop(0)                if task['cpu'] <= av['cpu'] and task['mem'] <= av['mem']:                    self.nodes[node_idx].add_task(task)                    break  class KubernetesScheduler(object):    """K8s 声明式调度:维护期望副本数,持续调和"""    def __init__(self, nodes, replicas):        self.nodes = nodes        self.desired = replicas        self.actual = 0     def reconcile(self):        gap = self.desired - self.actual        while gap > 0:            for node in self.nodes:                if node.add_task({'cpu': 1, 'mem': 1024, 'kind': 'pod'}):                    gap -= 1                    self.actual += 1                    break            else:                break        return gap  def main():    # YARN 演示:3 个任务放到 2 个节点上    yarn_nodes = [ResourceNode('y-node1', 8, 16384), ResourceNode('y-node2', 8, 16384)]    yarn = YARNScheduler(yarn_nodes)    for t in [{'cpu': 4, 'mem': 4096}, {'cpu': 4, 'mem': 4096}, {'cpu': 6, 'mem': 8192}]:        yarn.submit(t)    yarn.schedule()    print('YARN 剩余排队任务数:', len(yarn.queue))     # Mesos 演示:节点先发 Offer,再按需调度 2 个任务    mesos_nodes = [ResourceNode('m-node1', 8, 16384), ResourceNode('m-node2', 8, 16384)]    mesos = MesosScheduler(mesos_nodes)    print('Mesos 收到的 Offer 数:', len(mesos.get_offers()))    mesos.schedule([{'cpu': 4, 'mem': 4096}, {'cpu': 4, 'mem': 4096}])    print('Mesos 第一个节点任务数:', len(mesos_nodes[0].tasks))     # K8s 演示:期望 5 个副本,持续调谐直到满足    k8s_nodes = [ResourceNode('k-node1', 4, 8192), ResourceNode('k-node2', 4, 8192)]    k8s = KubernetesScheduler(k8s_nodes, 5)    gap = k8s.reconcile()    print('K8s 期望副本数为 5, 当前为', k8s.actual, ', 仍未满足', gap, '个')  if __name__ == '__main__':    main()
目的:用不到 100 行实现三种调度模式的核心逻辑,直观对比「集中排队」「Offer 撮合」「声明式调和」的运作差异。
  1. class ResourceNode模拟一个计算节点,负责记录已放任务并实时计算剩余资源。
  2. def available(self)返回节点当前剩余 CPU 和内存,是三种调度器共同依赖的「资源台账」。
  3. def add_task(self, task)先检查资源是否充足,再放入任务,模拟物理分配动作。
  4. YARNScheduler.schedule()遍历等待队列,尝试把每个任务放到第一个能容纳的节点,体现集中式「一条龙分配」。
  5. class MesosScheduler维护节点列表,通过 get_offers() 生成资源 Offer 列表。
  6. def get_offers(self)收集所有仍有剩余资源的节点,模拟 master 向 framework 推送 Offer。
  7. KubernetesScheduler.reconcile()对比期望副本数与当前实际数,循环补齐差距,体现声明式的「持续调谐」。
  8. KubernetesScheduler.actual记录当前已创建的 Pod 数量,是调和循环的反馈变量。

常见误区

误区很多人一听到 YARN 就联想到 MapReduce,认为 YARN 是个「批处理专用调度器」,跑不了其他任务。

正解YARN 本质是通用资源管理系统,它只负责分配 Container,不关心里面跑什么。Spark、Flink、Tez、MapReduce 都可以运行在 YARN 上。就像招待所前台只负责开房,住客是出差还是旅游,前台并不关心。

为何常见:Hadoop 生态早期最著名的组合是「MapReduce on YARN」,导致大家把 YARN 和批处理绑定。

误区有初学者看到 Mesos 社区不活跃,断言「这东西过时了,不用学」。

正解Mesos 的双层调度思想是分布式系统的经典案例,后来 K8s 的架构、Spark 的集群模式都借鉴了它的理念。而且 Twitter 等公司的大规模集群仍在生产环境中使用 Mesos,存量维护需求巨大。

为何常见:把「社区活跃度」误当成「技术价值」的唯一标尺,忽略了设计思想的长期影响。

误区有人觉得「不都是给任务分配资源的吗?那用哪个都行」。

正解两者抽象层次完全不同。YARN 调度的是 Container,服务发现、配置管理、自动弹性一概不管;K8s 不仅调度 Pod,还负责流量路由、滚动升级、故障自愈。选错底层会导致上层业务模型不得不迁就平台能力,改造代价巨大。

为何常见:单看「调度」两个字,忽略了二者在服务发现、存储编排、生命周期管理上的巨大差异。

误区部分团队选调度器时只跑调度吞吐率测试,谁快选谁。

正解调度吞吐只是众多维度之一。生态成熟度决定团队能否快速上手,运维复杂度决定日常故障成本,云原生趋势决定平台 3 年后是否过时。用加权评分法把多个维度量化,比单纯比性能更科学。

为何常见:性能数据最容易量化,而生态和运维的价值短期难以感知,导致决策者倾向于「拿数字说话」。

面试题

Q1. YARN 中负责全局资源调度的核心组件是?

单选题 · easy

  • A.NodeManager
  • B.ResourceManager← 正确答案
  • C.ApplicationMaster
  • D.Container

答案:B。ResourceManager(RM)是 YARN 的全局调度核心,相当于招待所总台;NodeManager 是节点代理,ApplicationMaster 是具体应用的管理者,Container 则是资源分配的结果。答错一般是把 RM 和 AM 的职责搞混。

Q2. Mesos 双层调度中,第一层由 master 向 framework 通过什么机制分发资源?

单选题 · mid

  • A.资源队列
  • B.资源打分
  • C.资源 Offer← 正确答案
  • D.抢占控制

答案:C。Mesos 的 master 把空闲资源封装成 Offer 推送给 framework,由 framework 选择接受或拒绝,这就是双层调度中第一层的关键机制。队列和打分是调度策略而非第一层机制,抢占属于异常处理。

Q3. Kubernetes 调度器在决定 Pod 放到哪个节点时,采用的两步过程是?

单选题 · mid

  • A.排队 + 出队
  • B.过滤 + 打分← 正确答案
  • C.Offer + 接受
  • D.广播 + 投票

答案:B。K8s 调度器先通过过滤(Predicate)排除不满足硬性条件的节点,再通过打分(Priority)在候选节点中选出最优。这和 Mesos 的 Offer 撮合、YARN 的队列调度有本质区别。

Q4. Kubernetes 中最小的调度和部署单元是?

单选题 · easy

  • A.Pod← 正确答案
  • B.Container
  • C.Service
  • D.Deployment

答案:A。Pod 是 K8s 的最小调度单元,一个 Pod 内可以包含一个或多个容器共享网络和存储。Container 是 Pod 内部的最小运行实体,Service 和 Deployment 是更高层面的抽象对象。

Q5. YARN 的 ResourceManager 实现高可用通常依赖哪个分布式协调组件完成选主?

单选题 · mid

  • A.etcd
  • B.ZooKeeper← 正确答案
  • C.Consul
  • D.Redis

答案:B。YARN 的 Active/Standby RM 依靠 ZooKeeper 做领导者选举和状态存储,这是 Hadoop 生态的经典配套。etcd 是 K8s 的存储组件,Consul 多用于服务发现,Redis 不是分布式协调工具。

Q6. 关于 Mesos 双层调度机制,下列说法正确的是?

多选题 · hard

  • A.第一层由 master 向 framework 推送资源 Offer← 正确答案
  • B.framework 可以拒绝 Offer 等待更合适的资源← 正确答案
  • C.Mesos master 决定每个任务运行在哪个节点
  • D.多个 framework 可以共享同一集群← 正确答案

答案:ABD。Mesos master 只分配资源 Offer,具体任务如何放置由 framework 自己的调度器决定(第二层),所以 C 错。拒绝 Offer 是 framework 表达偏好的重要手段,多 framework 共享集群正是 Mesos 的核心设计目标。

Q7. 在 Kubernetes 的资源模型中,requests 和 limits 分别代表?

单选题 · easy

  • A.最小申请量与最大限制量← 正确答案
  • B.最大限制量与最小申请量
  • C.已使用量与剩余量
  • D.高峰用量与低峰用量

答案:A。requests 是调度时的保底需求,相当于「这间房空调必须开到 26 度」;limits 是运行时硬上限,超过会被限制或杀掉,相当于「最高只能开到 30 度」。两者含义相反,不能颠倒。

Q8. 相比 YARN,Kubernetes 在以下哪些方面有明显差异?

多选题 · mid

  • A.声明式 API 与调和循环← 正确答案
  • B.内置弹性伸缩与滚动升级← 正确答案
  • C.只能运行批处理任务
  • D.面向云原生应用生态← 正确答案

答案:ABD。K8s 是通用容器编排平台,既能跑无状态服务也能跑有状态任务和批处理 Job,C 说法过于绝对。声明式 API、自动伸缩、滚动升级和云原生生态确实是 K8s 相对 YARN 的核心差异。

Q9. DRF(主导资源公平)算法是下面哪个系统核心的公平分配策略?

单选题 · hard

  • A.YARN 的 Capacity Scheduler
  • B.Mesos 的资源分配模块← 正确答案
  • C.K8s 的 Default Scheduler
  • D.Hadoop 的作业调度器

答案:B。DRF 是 Mesos 采用的资源公平算法,它把每位用户「占用量最大的那种资源」拿来比较,使多资源分配达到公平。YARN 的 Capacity 用队列权重分配,K8s 默认调度器用过滤加分,都不是 DRF 的主场。

Q10. 做集群调度器选型时,合理的评估维度包括?

多选题 · mid

  • A.生态成熟度与社区活跃度← 正确答案
  • B.运维复杂度与故障恢复能力← 正确答案
  • C.目标工作负载的类型← 正确答案
  • D.单机 CPU 主频高低

答案:ABC。选型应综合生态、运维、负载类型等维度,用加权评分法量化比较。单机 CPU 主频是硬件选型指标,与调度器选型无直接关系,因此 D 不选。