为放置任务排列候选节点
SwarmKit 的调度决策树在叶子中使用 nodeMaxHeap,把候选节点整理为从优到劣的顺序。
相关概念
工程问题#
调度不仅要过滤不能运行任务的节点,还要按比较规则给剩余候选排序;节点状态变化后要重新评估可行性。
实际实现#
orderedNodes 在必要时重新过滤并 heap.Init。最大堆每次弹出最差节点并放到数组末端,全部弹出后得到优先候选在前的数组。
处理流程#
- 在决策树叶子收集候选节点
- 重新检查约束并建立最大堆
- 逐个弹出最差候选放到末端
- 使用形成的有序候选数组
源码片段#
固定版本 · 原文摘录manager/scheduler/decision_tree.go1fd637ba5cc32ff30d1dd2bdb14997bd4f424b46 · L43–L52
43 // Popping every element orders the nodes from best to worst. The44 // first pop gets the worst node (since this a max-heap), and puts it45 // at position n-1. Then the next pop puts the next-worst at n-2, and46 // so on.47 for dt.nodeHeap.Len() > 0 {48 heap.Pop(&dt.nodeHeap)49 }5051 return dt.nodeHeap.nodes52}decisionTree.orderedNodes
这里会弹出堆中的全部节点。由于 nodeMaxHeap 的 Pop 保留底层切片并缩小逻辑长度,最差候选依次落在尾部,最后返回优先候选在前的数组;这不是每次从最小堆取一个最优节点。
收益与取舍#
工程分析带来的收益
- 复用切片存储完成堆排序
- 比较规则可与堆结构分离
付出的代价
- 工程分析:完整排序通常需要 O(n log n)
- 节点状态改变后需要重新过滤和建堆
可比较的选择
直接扫描取最优仅需一个候选时可能更简单;需要完整次序时要重复扫描。
版本与适用范围#
对应 SwarmKit 调度器的候选排序环节;这里是最大堆生成有序数组,不是每次只弹出最优节点的最小堆。
参考来源#
源码、官方文档与原始论文01
swarmkit · decisionTree.orderedNodes
源码1fd637ba5cc32ff30d1dd2bdb14997bd4f424b46manager/scheduler/decision_tree.go · decisionTree.orderedNodes
02
swarmkit · nodeMaxHeap
源码1fd637ba5cc32ff30d1dd2bdb14997bd4f424b46manager/scheduler/nodeheap.go · nodeMaxHeap