这是 Nomad 系列文章的第五章。在上一章,我们了解了 MemDB 如何作为集群的“记忆”存储状态。现在,当状态发生变化(例如用户提交了一个新作业,或者一台机器突然宕机),Nomad 必须做出反应。
这种“感知变化并计算应对方案”的过程,就是本章的主角——评估 (Evaluation)。
前言:不要为了调度而调度
在 Nomad 中,"调度"并不是一个持续运行的死循环,而是事件驱动的。
当集群处于静默状态时,调度器是完全休眠的。只有当某种“事件”打破了平静,Nomad 才会生成一个 Evaluation(简称 Eval)。你可以把 Eval 看作是一张**“体检单”**,它告诉调度器:“嘿,集群的状态变了,请重新评估一下这个 Job 还需要什么资源。”
本章我们将揭秘 Nomad 如何通过 Eval 机制,在毫秒级内完成复杂的调度决策。
1. 触发器:谁动了我的集群?
Eval 不会凭空产生,它总是由特定的事件触发。常见的触发场景包括:
- Job Register:用户提交或更新了一个作业(最常见)。
- Node Update:一个 Client 节点加入、甚至或者资源发生变化。
- Node Failure:心跳检测机制发现某节点 Down 了,系统自动触发 Eval 来迁移该节点上的任务。
- Periodic:定时任务触发。
一旦生成,Eval 就会被送入一个核心组件——Eval Broker。
2. 调度总管:Eval Broker
Eval Broker 是调度引擎的“交通指挥官”。它的主要职责是管理所有待处理的评估请求,确保重要的任务优先得到处理。
根据源码分析,Eval Broker 具备以下关键特性:
- 优先级队列:它不仅仅是先进先出 (FIFO)。Service 类型的作业(如 Web 服务)通常比 Batch 类型的作业(如离线计算)拥有更高的优先级。
- 至少一次传递 (At-least-once Delivery):确保每个 Eval 最终都会被调度器处理,不会因为网络抖动而丢失。
- 超时与重试:如果一个调度器领取了任务却迟迟不反馈(比如处理该 Eval 的 Server 挂了),Broker 会在超时后将该 Eval 重新放回队列,分配给其他 Server。
3. 分布式调度:Follower 也能干活
这是 Nomad 架构中极其精妙的一点。
我们知道 Raft Leader 负责所有的写操作,但如果所有的调度计算(CPU 密集型任务)也都由 Leader 承担,Leader 很快就会被累垮。
Nomad 采用了 “乐观并发 (Optimistic Concurrency)” 的设计来实现分布式调度:
- 分发:Leader 上的 Eval Broker 可以将 pending 状态的 Eval 分发给集群中的 Follower 节点。
- 并行计算:Follower 节点运行调度算法(Feasibility Checking -> Ranking),计算出最佳的放置方案。
- 提交计划:Follower 算好后,生成一个 Plan,发回给 Leader。
- 最终裁决:Leader 检查这个 Plan 是否有效(例如:Plan 说要把任务放在节点 A,Leader 会检查节点 A 的资源在这一瞬间是否依然充足)。
- 通过:写入 Raft Log,生成 Allocation。
- 冲突:驳回 Plan,Follower 重新计算。
这种设计使得 Nomad 的调度吞吐量可以随着 Server 节点的增加而线性增长。
4. 调度三部曲:过滤、打分、选优
当一个调度器(无论是 Leader 还是 Follower)拿到 Eval 后,它会执行以下逻辑:
-
可行性检查 (Feasibility Checking):
- 遍历 MemDB 中的 Node 表。
- 剔除不符合硬性约束的节点(如:CPU 不够、缺少特定 Driver、不满足
constraint标签)。
-
打分与排名 (Ranking):
- 对剩下的候选节点进行打分。
- Binpack(装箱)策略:优先填满一台机器,节省资源(适合云环境省钱)。
- Spread(打散)策略:尽可能把副本分散到不同机器、机架或数据中心(适合高可用)。
-
生成计划 (Plan):
- 选出得分最高的节点,生成一个“拟定”的分配方案。
5. 架构图解:Eval 的一生
让我们通过 Mermaid 图来看清一个 Eval 是如何流转的:
6. 总结
Nomad 的调度引擎展示了如何在一致性与性能之间取得平衡:
- Eval 是核心对象:它是连接状态变化与调度动作的载体。
- Broker 是调度中枢:保证了任务调度的有序性和可靠性。
- 分布式计算:通过让 Follower 参与计算,Nomad 避免了单点计算瓶颈,能够轻松支撑 10,000+ 节点的集群。
理解了 Nomad 如何制定“作战计划”,下一章我们将把视角转回 Client 端,深入了解 Client 的启动与注册流程,看看这些执行单元是如何加入集群并时刻准备接受任务的。
1909



被折叠的 条评论
为什么被折叠?



