什么是 YARN 的资源抢占(Preemption)机制?为什么需要资源抢占?
在 Hadoop YARN 中,资源抢占(Resource Preemption)是调度器(如 Capacity Scheduler 或 Fair Scheduler)的一项高级特性。它允许集群在资源紧张时,从那些超额使用资源的队列或任务中强行收回资源,并分配给资源不足且拥有更高优先级(或未达到其保证容量)的队列。
为了让你更容易理解,我们先解答“为什么需要资源抢占”,再解释“它是如何工作的”。
一、 为什么需要资源抢占?(Why?)
资源抢占主要是为了解决“资源弹性共享”与“资源最低保证(SLA)”之间的矛盾。
场景举例:
假设你的 YARN 集群总资源是 100G 内存。有两个部门(队列):
- 队列 A(核心业务): 保证容量为 50G。
- 队列 B(边缘业务): 保证容量为 50G。
没有资源抢占的情况:
- 晚上 8 点,核心业务 A 闲置没有任务,边缘业务 B 提交了大量计算任务。
- YARN 为了不浪费集群资源(弹性共享机制),允许队列 B 借用队列 A 的闲置资源。于是,队列 B 占用了 100G 的全部资源。
- 晚上 9 点,核心业务 A 突然爆发,需要 50G 的资源(这本来就是它应得的保证容量)。
- 但是,因为队列 B 的任务正在运行中且尚未结束,队列 A 无法获得资源,只能干等。这导致核心业务严重延迟,违反了 SLA。
引入资源抢占后的情况:
当核心业务 A 需要资源时,YARN 调度器发现队列 B 占用的资源超过了它的保证容量(50G),且队列 A 处于“饥饿”状态。于是,YARN 会强制终止(Kill)队列 B 中的部分任务(归还借走的 50G),把空出来的资源立刻分配给队列 A,从而保证核心业务的顺利运行。
总结原因:
- 保障核心队列的 SLA: 确保每个队列在需要时,随时都能获得其配置的“保证资源(Minimum/Guaranteed Capacity)”。
- 提高集群整体利用率: 允许资源在闲置时被跨队列借用(弹性),但在需要时能及时收回,避免了因为硬性隔离导致的资源浪费。
- 防止恶意或死循环任务霸占集群: 避免低优先级的长耗时任务长时间占据资源不释放。
二、 什么是 YARN 的资源抢占机制?(What & How?)
资源抢占机制是 YARN Resource Manager (RM) 的一部分,具体工作流程如下:
1. 监控与计算(识别谁被饿死了,谁吃撑了)
YARN 的调度器会周期性地扫描所有队列的使用情况。它会计算出哪些队列处于资源饥饿状态(实际使用量 < 保证容量,且有等待任务),以及哪些队列处于资源超额状态(实际使用量 > 保证容量)。
2. 优雅地请求归还(Graceful Ask)
YARN 并不会上来就直接杀掉任务。Resource Manager 会先向“超额队列”中的 ApplicationMaster (AM) 发送一个通知,要求它主动释放一些 Container(资源容器)。
- “嘿,你借的资源该还了,请你自己把快运行完的任务结束掉,把资源交出来。”
3. 等待超时(Timeout)
Resource Manager 会给 ApplicationMaster 一段宽限时间(通常可以通过参数配置,比如 15 秒)。如果 AM 在这个时间内主动归还了足够的资源,抢占过程就结束了。
4. 强制终止(Forceful Kill)
如果超过了宽限时间,ApplicationMaster 还是没有归还足够的资源,Resource Manager 就会采取强制措施。它会指示 NodeManager 直接 Kill 掉超额队列中正在运行的 Container。
- 被 Kill 掉的任务进度会丢失,资源被立刻强行收回,并分配给饥饿的队列。
- 被 Kill 掉的任务(Container)通常会被 ApplicationMaster 标记为失败,并在之后重新排队等待执行。
三、 使用资源抢占的注意事项
虽然资源抢占很好地解决了资源分配的矛盾,但在实际生产环境中使用时需要注意以下几点:
- 任务失败与重试: 抢占会导致正在运行的 Container 被 Kill,这意味着这些任务(如 Map/Reduce task、Spark task)之前完成的计算工作会白费,需要重新计算。因此,抢占是以牺牲被抢占任务的计算时间为代价的。
- 默认是关闭的: 在标准的 Hadoop 配置中,资源抢占通常默认是关闭的(
yarn.resourcemanager.scheduler.monitor.enable=false)。因为频繁的抢占会导致集群计算效率低下(大量任务被 Kill 后重试,造成资源浪费)。 - 需要精心调优: 开启抢占后,需要配置多个参数,例如:
- 抢占的宽限时间(等多久才杀任务)。
- 每次最多允许抢占集群总资源的百分比(防止一次杀太多任务导致集群剧烈震荡)。
- ApplicationMaster 本身(AM Container)通常是免于被抢占的,否则整个应用都会失败。
总结:
YARN 的资源抢占机制是一种“纠偏”手段,它通过“先礼(请求)后兵(强杀)”的方式,在保证集群资源最大化共享的同时,坚决捍卫各个队列(或租户)最低的资源保障底线。