Google Borg 是资源调度治理和离在线混部畛域的鼻祖,同时也是 Kubernetes 的起源与参照,已成为从业人员首要学习的榜样。本文尝试管中窥豹,简略从《Large-scale cluster management at Google with Borg》一文中分析 Google Borg 的设计理念和性能特点,用以抛砖引玉。

Google Borg 是什么?

Google Borg 是 Google 外部自研的一套资源管理零碎,用于集群资源管控、调配和调度等。在 Borg 中,资源的单位是 Job 和 Task。Job 蕴含一组 Task。Task 是 Borg 治理和调度的最小单元,它对应一组 Linux 过程。相熟 Kubernetes 的读者,能够将 Job 和 Task 大抵对应为 Kubernetes 的 Service 和 Pod。

在架构上,Borg 和 Kubernetes 相似,由 BorgMaster、Scheduler 和 Borglet 组成。

Borg Allocs

Borg Alloc 代表一组可用于运行 Task 的资源,如 CPU、内存、IO 和磁盘空间。它实际上是集群对物理资源的形象。Alloc set 相似 Job,是一堆 Alloc 的汇合。当一个 Alloc set 被创立时,一个或多个 Job 就能够运行在下面了。

Priority 和 Quota

每个 Job 都能够设置 Priority。Priority 可用于标识 Job 的重要水平,并影响一些资源分配、调度和 Preemption 策略。比方在生产中,咱们会将作业分为 Routine Job 和 Batch Job。Routine Job 为生产级的例行作业,优先级最高,它占用对应理论物理资源的 Alloc set。Batch Job 代表一些长期作业,优先级最低。当资源缓和时,集群会优先 Preempt Batch Job,将资源提供给 Routine Job 应用。这时 Preempted Batch Job 会回到调度队列期待从新调度。

Quota 代表资源配额,它束缚 Job 的可用资源,比方 CPU、内存或磁盘。Quota 个别在调度之前进行查看。Job 若不满足,会立刻在提交时被回绝。生产中,咱们个别根据理论物理资源配置 Routine Job Quota。这种形式能够确保 Routine Job 在 Quota 内肯定有可用的资源。为了充沛晋升集群资源使用率,咱们会将 Batch Job Quota 设置为有限,让它尽量去占用 Routine Job 的闲置资源,从而实现超卖。这方面内容前面会在再次详述。

Schedule

调度是资源管理零碎的外围性能,它间接决定了零碎的“好坏”。在 Borg 中,Job 被提交后,Borgmaster 会将其放入一个 Pending Queue。Scheduler 异步地扫描队列,将 Task 调度到有短缺资源的机器上。

通常状况下,调度过程分为两个步骤:Filter 和 Score。

  • Filter,或是 Feasibility Checking,用于判断机器是否满足 Task 的束缚和限度,比方 Schedule Preference、Affinity 或 Resource Limit。
  • Filter 完结后,就须要 Score 符合要求的机器,或称为 Weight。上述两个步骤实现后,Scheduler 就会筛选相应数量的机器调度给 Task 运行。实际上,抉择适合的调度策略尤为重要。

这里能够拿一个咱们生产遇到的调度问题举例。

生产初期,咱们的调度零碎采纳的 Score 策略相似 Borg E-PVM,它的作用是将 Task 尽量平均的调度到整个集群上。从侧面成果上讲,这种策略扩散了 Task 负载,并在肯定水平上放大了故障域。但从背面看,它也引发了资源碎片化的问题。因为咱们底层环境是异构的,机器配置并不对立,并且 Task 配置和物理配置并无对应关系。这就造成一些配置过大的 Task 无奈运行,由此在肯定水平上升高了资源的分配率和使用率。

为了应酬此类问题,咱们自研了新的 Score 策略,称之为 “Best Fillup”。它的原理是在调度 Task 时抉择可用资源起码的机器,也就是尽量填满。不过这种策略的毛病不言而喻:单台机器的负载会升高,从而减少 Bursty Load 的危险;不利于 Batch Job 运行;故障域会减少。

本篇论文作者采纳了一种被称为 hybrid 的形式,据称比第一种策略减少 3-5% 的效率。

Utilization

资源管理零碎的首要指标是进步资源使用率,Borg 亦是如此。不过因为过多的前置条件,诸如 Job 搁置束缚、负载尖峰、多样的机器配置和 Batch Job,导致不能仅抉择 “average utilization” 作为策略指标。在Borg中,应用Cell Compaction 作为评判基准。简述之就是:能承载给定负载的最小 Cell。

Borg 提供了一些进步 utilization 的思路和实际办法,有些是咱们在生产中曾经采纳的,有些则十分值得咱们学习和借鉴。

Cell Sharing

Borg 发现,将各种优先级的 Task,比方 prod 和 non-prod 运行在共享的 Cell 中能够大幅度的晋升资源利用率。

下面(a)图表明,采纳 Task 隔离的部署形式会减少对机器的需要。图(b)是对额定机器需要的散布函数。图(a)和图(b)都分明的表明了将 prod Job 和 non-prod Job 离开部署会耗费更多的物理资源。Borg 的教训是大概会新增 20-30% 左右。

个中原理也很好了解:prod Job 通常会为应答负载尖峰申请较大资源,实际上这部分资源在少数工夫里是闲置的。Borg 会定时回收这部分资源,并将之调配给 non-prod Job 应用。在 Kubernetes 中,对应的概念是 request limit 和 limit。咱们在生产中,个别设置 Prod Job 的 Request limit 等于 limit,这样它就具备了最高的 Guaranteed Qos。该 QoS 使得 pod 在机器负载高时不至于被驱赶和 OOM。non-prod Job 则不设置 request limit 和 limit,这使得它具备 BestEffort 级别的 QoS。kubelet 会在资源负载高时优先驱赶此类 Pod。这样也达到了和 Borg 相似的成果。

Large cells

Borg 通过试验数据表明,小容量的 cell 通常比大容量的更占用物理资源。

这点对咱们有很重要的指导意义。通常状况下,咱们会在设计集群时对容量问题感到当机立断。

不言而喻,小集群能够带来更高的隔离性、更小的故障域以及潜在危险。但随之带来的则是治理和架构复杂度的减少,以及更多的故障点。

大集群的优缺点正好相同。在资源利用率这个指标上,咱们凭直觉认为是大集群更优,但苦于无松软的理论依据。Borg 的钻研表明,大集群有利于减少资源利用率,这点对咱们的决策很有帮忙。

Fine-grained resource requests

Borg 对资源细粒度调配的办法,目前已是支流,在此就不再赘述。

Resource reclamation

理解 Kubernetes 的读者,应该对 resource request 和 limit,在 Google Borg 中概念相似。Job 在提交时须要指定 resource limit,它能确保外部的 Task 有足够资源能够运行。

有些用户会为 Task 申请过大的资源,以应答可能的申请或计算的突增。但实际上,局部资源在少数工夫内是闲置的。与其资源节约,不如利用起来。这须要零碎有较准确的预测机制,能够评估 Task 对理论资源的需要,并将闲置资源回收以调配给低 priority 的工作,比方 Batch Job。

上述过程在 Borg 中被称为 resource reclamation,对应用资源的评估则被称为 reservation。Borgmaster 会定期从 Borglet 收集 resource consumption,并执行 reservation。在初始阶段,reservation 等于 resource limit。随着 Task 的运行,reservation 就变为了资源的理论使用量,外加 safety margin。

在 Borg 调度时,Scheduler 应用 resource limit 为 prod Task 过滤和抉择主机,这个过程并不依赖 reclaimed resource。从这个角度看,并不反对对 prod Task 的资源超卖。但 non-prod Task 则不同,它是占用已有 Task 的 resource reservation。所以 non-prod Task 会被调度到领有 reclaimed resource 的机器上。

这种做法当然也是有肯定危险的。若资源评估呈现偏差,机器上的可用资源可能会被耗尽。在这种状况下,Borg 会杀死或者降级 non-prod Task,prod Task 则不会受到任何影响。

上图证实了这种策略的有效性。参照 Week 1 和 4 的 baseline,Week 2 和 3 在调整了 estimation algorithm 后,理论资源的 usage 与 reservation 的 gap 在显著放大。在 Borg 的一个 median cell 中,有 20% 的负载是运行在 reclaimed resource 上。

相较于 Borg,Kubernetes 尽管有 resource limit 和 capacity 的概念,但却短少动静 reclaim 机制。这会使得系统对低 priority Task 的资源短少卓有成效的评估机制,从而引发零碎负载问题。这个性能对资源调度和晋升资源使用率影响微小。

Isolation

因为 Google Borg 天生就思考混部场景,所以资源隔离对其尤为重要。在外部场景,Google Borg 多应用 Linux 隔离,比方 chroot、cgroup 等,相似容器隔离机制。私有云侧,Google Borg 则通过 VM 或沙箱技术实现 Task 间的强隔离。

在性能隔离方面,Google Borg 通过辨别利用优先级的形式保障服务质量。latency-sensitive(LS) 高优工作领有高的资源保障,Batch 低优工作占用资源则会依据须要被克制。

在集群资源方面,Google Borg 将之分为可压缩和不可压缩资源。与流速相干的资源,诸如 CPU、磁盘 IO 等,被定义为可压缩资源。这部分资源若被耗尽,Borglet 会首先降级解决低优工作,而不是间接杀死。这种做法能最大水平保障低优工作服务质量。不可压缩资源,包含内存、磁盘空间等,在资源缓和时,工作会被依照优先级从低到高杀死,直到缓和状况缓解。

在内核层面,Google Borg 同样有策略保障资源隔离与复用。比方 LS 工作可独享物理 CPU 外围,其余 LS 工作不可复用。Batch 工作能共用这部分 CPU,通过设置低 cpus_share 的形式与 LS 工作隔离。Borget 也会周期性的调整 LS 工作,以防止 Batch 工作被饿死。为了反对高敏工作,Google Borg 对 CFS 做了加强,使之可依据 cgroup 负载预测提前抢占 Batch 工作,从而升高 CFS 调度提早。

总结

离在线混合部署是一套简单的零碎和技术,须要从方法论、业务、利用、资源调度零碎、操作系统等多个层面的实现和配合,并且也须要长期的实战和教训积攒。Google Borg 作为 Google 外部的教训结晶,零碎的论述了混部应有的根本状态,很有启发意义。目前咱们在腾讯外部也开发和上线了一套基于 Kubernetes 的离在线混合部署零碎,反对动静资源预测、资源回收和内核级隔离。后续会继续分享混部相干的实践和实战经验。

参考资料

  1. Large-scale cluster management at Google with Borg:https://iwiki.oa.tencent.com/...
  2. evolution of cluster scheduler architecture:http://www.firmament.io/blog/...
  3. poseidon:https://github.com/kubernetes...
  4. design:https://docs.google.com/docum...
  5. firemament:https://github.com/camsas/fir...
【腾讯云原生】云说新品、云研新术、云游新活、云赏资讯,扫码关注同名公众号,及时获取更多干货!!