谷歌Borg论文阅读笔记(二)——任务混部的解决

简介: BorgMaster在全局进行任务调度和分配资源,Borglet管理主机层面的资源隔离。

总算又往下读了一部分。Google的Borg论文中,前面部分讲的都是Borg的架构。后面有讲了一些资源隔离,安全隔离等的技术方案和策略。

主机层面的资源隔离,都是由是Borglet来操纵的。

Google的混部情况:

Google几乎所有的机器都是混部的,在一台机器上,可能运行着不同jobs的tasks。根据论文中所说,Google的50%的机器运行了9个甚至更多的tasks。90%的机器运行着25个tasks,达到4500个线程。

因此,Google有完善的隔离技术来保证task之间不相互影响。目前,Google使用的隔离技术是Chroot和CgroupCgroup本来就是Google最先提交到内核社区的,应该就是为了解决Borg的隔离。

对于外部的软件,比如GAE和GCE,Google的做法是让它们运行在虚拟机(KVM)上,KVM进程被作为Borg的task运行。也就是说,Borg是作为下层的,KVM运行在它之上

资源共享的问题:

资源共享带来的问题主要就是两个,一个是安全,一个是资源之间的性能影响

安全方面:

系统采用了Chroot隔离了文件系统。对于程序的调试,全都通过Borg来操作,Borg会让用户的命令在和被操作的tasks同一个容器下的shell中运行。

性能影响:

对于性能的影响,Google使用了很多技术来减少影响,这个是文章后面详细讲的。这里主要讲的是Google对任务混部对CPU性能影响的研究。

Google为了评估不同任务部署到同一个机器的CPU干扰影响做了一个实验。他们使用CPI(每条计算机指令执行所需的时钟周期)来衡量性能干扰。CPI增加一倍,CPU密集型程序运行时间就会增加一倍,对应于即时相应的程序,可能就是延时增加了一倍

实验发现,CPI和2个相同时间间隔的测量成正相关机器的整体CPU使用率,以及运行在机器上的tasks

  1. 添加一个task到一台机器上,会增加别的任务0.3%的CPI(使用线性模拟合数据)。
  2. 增加10%的CPU利用率会增加2%的CPI。

这是CPU密集型的程序测量的结果,事实上干扰存在于各种资源。

相对而言,专用的cells的CPI要低于混用的cells。据Google的统计,共享cells的CPI平均值为1.58(σ = 0.35)。在专用cells中,CPI平均值为1.53(σ = 0.32),CPU性能在共享cells中有大约下降3%。

但这也表明,使用共享的cells并没有大幅度增加程序运行的成本,而在机器需求方面,共享的cells更节约机器。另外。共享的优势适用于所有资源,包括内存和磁盘,而不仅仅是CPU。当然,Google还是有些特别的服务是放在专用的cell上的。

Google也对cell的大小进行了评估,发现cell越大越节约机器

任务分类:

Google对jobs是分类为prod和non-prod的。prod指的是面向应用这类jobs,non-prod指的是批处理这类jobs。对于主机上的tasks,则是分为延迟敏感型(latency-sensitive)批处理(rest)。因为non-prod的jobs中的master应该也是延迟敏感的,所以需要在task上进行分类。

个人理解:non-prod和prod是在BorgMaster调度时看的,是一个全局的维度。而latency-sensitive和rest是Borglet在主机的task层面上看的,是一个资源分配的维度。

另外,Borg中,主机的资源其实是超卖的(不然怎么节约资源),包括可压缩和不可压缩的资源。因此,可能会出现所有tasks都没有超过限制值,而主机资源不足的情况。此时,就需要根据task的分类来进行取舍。

延迟敏感型(latency-sensitive):

未作特殊说明,下面采用缩写LS tasks来表示延迟敏感型的任务。

LS tasks用于面向用户的应用,以及共享设施服务,它需要快速响应请求。高优先的LS tasks享受最好的待遇。能暂时让批处理饥饿几秒钟。

批处理(rest):

用于离线计算的进程,用于利用那些再生资源。基本是说被kill就被kill。

资源分类:

混部的一大问题是某个资源不足的情形。但是,不同的资源有不同的特点,有的资源能快速调整,而有的则需要很大的代价来调整。因此,Borg将资源分为两大类:可压缩资源(compressible resources)不可压缩资源(non-compressible resources)

可压缩资源(compressible resources)

这种资源指的是CPU,磁盘IO这类资源。它们是基于比例的,可以通过降低服务质量来调整资源分配,这种调整消耗的代价极少,几乎可以忽略

可用的方案:

  • CPU:Cgroup中的cpu子系统,可以限流CPU执行周期,也可以调整调度权重。
  • IO:Cgroup中的disk子系统,可以在块设备层面限流IOPS和流量。也能在更底层的IO调度层调整权重(权重调整只支持CFQ,但是注意CFQ并不适合SSD)。

对LS tasks的优待:LS tasks可以保留完整的CPU核心,阻止其它LS tasks使用它们。批处理tasks可以运行在任何CPU核心下,但它被给予相对于LS tasks很小的调度份额。Borglet动态调整LS tasks的资源限制,为了确保它不会把批处理tasks饿死几分钟,在需要的时候,选择性的应用CFS控制带宽。

CFS改进:Cgroup中,CPU子系统是依赖于CFS调度算法,这是目前Linux的默认任务调度算法。Google为了减少调度延时和高利用率,调优了CFS调度程序。另外,Google的程序多采用多线程模型,这能减轻持续负载失衡的影响。

  • 允许对LS tasks抢占批处理的tasks。
  • 在多个对LS tasks在一个CPU下运行时,减少调度量。

主机资源超配:如果机器用尽了可压缩资源,Borglet会对某些task进行限流处理(给对LS tasks足够的资源)。这样,短负载峰值就可以被处理,而不需要kill掉任何tasks。如果情况没有改善,Borgmaster会从这台机器上迁移掉一些tasks。

不可压缩资源(non-compressible resources)

这种资源的典型代表就是内存,还有就是磁盘容量。此类资源的调整是很难的,比如内存,在内存不足的时候,Linux会进行内存回收,该刷盘的刷盘,写swap的写swap。如果这还不行,就会进入OOM-KILL流程。这个代价是很大的。

因此,如果不可压缩资源不足,就只能kill掉进程来回收资源,Google也是这么干的(操作系统也只能这么做)。

可用的方案:

  • 内存:Cgroup的memory子系统可以支持限制内存使用。Cgroup内的内存有自己的LRU链,所以Cgroup内部也会自动换页。此外,在Cgroup内的内存用尽之时,也会触发Cgroup内的OOM-KILL流程。另外,系统自身的OOM-KILL级别是高于Cgroup的。
  • 磁盘:这块不清楚Google是怎么做的,Cgroup也没有支持这个。有的软件是quota磁盘限额,可以限定文件夹内使用磁盘空间的大小,超过了就禁止写入。最早听说这是间隔扫描的方式,觉得不靠谱,现在应该改进成用inotify了。

主机资源超配:当不可压缩资源不足时,Borglet会从优先级最低的task开始kill,直到资源足够。

资源分配:

细粒度资源请求:

Google的资源分配是由用户申请的,用户可以指定各种资源的所需大小。而不是类似售卖虚拟那样有固定的规格。

Google对此做过实验,使用固定规格容器,根据CPU核心和内存两个维度的限制,四舍五入到下一个大于等于资源需求的规格。最小规格为0.5个CPU核心,1G内存。实验的结论是,这么做会增加30%-50%的资源开销。而且这还是在cell被压实之前的,压实后cell的资源开销更低。此外,cell还能支持CPU和内存的独立伸缩。

资源分配方法:

每个tasks和资源有3个相关的数据。分别是:申请值,估值,使用值

  1. 申请值:也就是限制值申请资源时,用户填写的值。
  2. 估值:Borg对程序使用资源量的估计,也被称为预定(reservation)。一般是使用值加上一定保护缓冲区。
  3. 使用值:当前task使用的资源值,是采集的数据。

估值是为了能回收利用那些没被用到的资源。每过几秒,BorgMaster会进行一次计算。

最初的估值会等于申请值,300秒之后,允许启动瞬变(startup transients),它会缓慢的向实际使用加上安全边缘靠拢如果使用量超过了估值,估值会迅速增加。

Borg调度者使用申请值(限制值)来计划prod tasks(分配时按照限制来算),因此它们从不依靠再生资源,也不会超额分配资源。对于non-prod tasks,它使用现有tasks的预定,所以新的任务能调度到再生资源(分配时按照现有估值来算)。

资源超限制值:

Tasks允许使用资源量通常在限制值内。但只要主机资源足够,就可以使用超出限制值的资源。当然,这会增加tasks被Kill掉的可能性。当BorgMaster分配任务时发现资源不足时,它会优先回收超过限制值的tasks的资源。

大多数tasks允许使用可压缩资源超过限制值。比如CPU,Borg以此来利用未被利用的(松弛)资源。在Google中,只有5%的LS task禁止使用资源超过限制值,大概是为了获得更好的可预测性。只有少于1%的批处理tasks这么做(禁止资源使用超过限制值)。

使用内存超过限制值默认是被禁止的,因为这增加了task被kill掉的机会。但即使如此,10%的LS tasks重写了这个(允许内存使用超过限制值)。79%的批处理任务这么做,因为这是MapReduce框架的默认设置。

总结:

总的来说,Google节约资源其实就是在合理的情况下,对资源进行了超分配。因为很多任务其实并不是任何时刻都会用很多资源的。

另外,Google对任务和资源进行了分类。总体上,以高优先的LS task为核心批处理任务以一个填坑的角色来吃掉剩余的资源。尽可能不kill掉tasks,万不得已情况下先拿低优先级开刀。

这确实是个很成熟的资源隔离方案,值得借鉴。

转载请注明:云计算技术手札 » 谷歌Borg论文阅读笔记(二)——任务混部的解决

目录
相关文章
|
4月前
|
人工智能 算法 调度
多智能体协作平台(MCP)实现多供应商AI生态系统中的互操作性
在现代人工智能(AI)领域,智能体的互操作性是实现系统协同的关键要素。随着多个供应商提供不同的智能体产品,如何在复杂的生态系统中构建互操作性的基础设施变得尤为重要。本文将探讨如何构建一个支持多供应商智能体互操作性的生态体系,重点讨论多供应商环境中的MCP(Multi-Agent Collaborative Platform)架构,解决不同智能体之间的协作与资源共享问题。
多智能体协作平台(MCP)实现多供应商AI生态系统中的互操作性
|
9月前
|
安全 Linux 开发工具
【Azure 环境】Azure 虚拟机上部署 DeepSeek R1 模型教程(1.5B参数)【失败】
遇见错误一:operator torchvision::nms does not exist 遇见错误二:RuntimeError: Failed to infer device type
811 22
|
传感器 弹性计算 人工智能
简介Multi-Agent
多智能体系统(MAS)是由多个自主智能体组成的计算系统,各智能体能独立决策、协同作业,无需中央控制。其特点包括自主性、分布性、交互性、异构性和适应性,广泛应用于人工智能、经济、交通、医疗和环保等领域,展现出巨大潜力。然而,MAS也面临通信开销、一致性、安全性和可扩展性等挑战。
830 3
|
资源调度 分布式计算 Kubernetes
Koordinator 支持 K8s 与 YARN 混部,小红书在离线混部实践分享
Koordinator 支持 K8s 与 YARN 混部,小红书在离线混部实践分享
|
存储 Kubernetes 固态存储
IEEE HPCA 2024|LightPool:高性能、轻量级的存储池化架构
IEEE HPCA 2024|LightPool:高性能、轻量级的存储池化架构
|
存储 运维 Kubernetes
Kubernetes HPA 的三个误区与避坑指南
云计算带来的优势之一便是弹性能力,云原生场景下Kubernetes提供了水平弹性扩容能力(HPA),让应用可以随着实时指标进行扩/缩。然而HPA的实际工作情况可能和我们直观预想的情况是不一样的,这里面存在一些认知误区。本文总结了一下 EDAS 用户在使用 HPA 时常遇到的三个认知误区
2645 101
Kubernetes HPA 的三个误区与避坑指南
|
负载均衡 安全 网络协议
如何通过计算巢在ACK集群上使用Istio服务网格
本文主要介绍怎么通过计算巢部署Isito服务网格,并介绍了使用示例。
|
缓存 Linux
百度搜索:蓝易云【Centos报错:[Errno 12] Cannot allocate memory怎么解决?】
请注意,如果内存不足的问题持续出现,建议考虑升级系统的物理内存或优化系统配置,以确保系统具有足够的资源来运行应用程序和服务。
264 0
|
canal 消息中间件 关系型数据库
大数据同步工具Canal 1
大数据同步工具Canal
944 0
|
数据采集 达摩院 资源调度
AHPA 弹性预测最佳实践
在云原生场景下,资源容量往往难以预估,而使用 K8s 原生的 HPA,往往要面对弹性滞后以及配置复杂问题。阿里云容器服务与达摩院决策智能时序团队合作推出的 AHPA(Advanced Horizontal Pod Autoscaler)弹性预测,可以根据业务历史指标,自动识别弹性周期并对容量进行预测,帮你提前进行弹性规划,解决弹性滞后的问题。 AHPA 如何配置才能解锁最佳使用姿势?本文给你带来 AHPA 弹性预测最佳实践
1920 0
 AHPA 弹性预测最佳实践