正文
每个任务映射到在机器上的容器中运行的一组Linux进程[62]。 大多数Borg工作负载不在虚拟机(VM)内运行,因为我们不想支付虚拟化的成本。此外,该系统是在我们对没有硬件的虚拟化支持的处理器进行大量投资的时候设计的。
任务也具有属性,例如资源需求和任务在作业中的索引。
大多数任务属性对作业中的所有任务是相同的,但是可以被重写 -
例如,以提供指定任务的命令行标志。每个资源维度(CPU核,RAM,磁盘空间,磁盘访问速率,TCP端口,等)以细粒度独立指定;
我们不强加固定大小的桶或槽(§5.4)。静态链接Borg程序以减少对其运行时环境的依赖,并且Brog程序被打包为二进制文件和数据文件,由Borg负责安装。
用户通过向Borg发出远程过程调用(RPC)来操作作业,最常见的是通过命令行工具,其他Borg作业或监视系统(§2.6)。大多数作业描述都是用声明性配置语言BCL编写的。BCL是GCL的一个变体[12],它生成protobuf文件[67],并扩展了一些Borg特定的关键字。GCL提供lambda函数以允许计算,应用程序可以使用它们来调整环境配置;
成千上万的BCL文件超过1k行长,我们已经积累了数千万行的BCL。Borg作业配置与Aurora配置文件相似[6]。
图2说明了作业和任务在其生命周期中经历的状态。
图2:作业和任务的状态图。 用户可以触发提交,终止和更新转换。
用户可以通过推送新的作业配置到Borg,再指示Borg将任务更新到新配置,来更改正在运行的作业中的某些任务或所有任务的属性。
这是一个轻量级的非原子事务,可以很容易地被撤销,直到它被关闭(提交)。
更新通常以滚动方式完成,并且可以对更新导致的任务中断(重新计划或抢占)的数量加以限制; 跳过会导致更多中断的任何更改。
某些任务更新(例如,推送新的二进制)总是需要重启任务; 某些更新(例如,增加的资源需求增加或约束改变)可能使得任务不再适合于这台机器,将导致任务停止并重新调度; 而某些更新(例如,改变优先级)却可在不重新启动或移动任务的情况下进行。
任务可以要求在被SIGKILL抢占之前通过Unix SIGTERM信号获取通知,这样任务就有时间进行清理,保存状态,完成当前正在执行的请求并拒绝新的请求。 如果抢占者设置延迟界限,则实际通知可能更少。 在实践中,通知传递约80%的时间。
2.4 分配
Borg
alloc(分配的简称)是可以运行一个或多个任务的机器上的一组保留资源;无论资源是否被使用仍然被分配。Alloc可以用于为将来的任务设置资源,在停止和重启任务之间保留资源,以及将不同作业中的任务收集到同一台机器上
- 例如,Web服务实例和相关的日志保存任务, 这个任务将服务的URL日志从本地磁盘复制到分布式文件系统。
alloc的资源以类似于机器资源的方式处理;
多个任务运行在一个alloc中,共享其资源。如果一个alloc必须重定位到另一台机器,它的任务将被重新调度。
一个alloc集合就像一个作业:它是一组在多个机器上预留资源的alloc。
一旦创建了一个alloc集,可以提交一个或多个作业在其中运行。
简单期间,我们一般会使用“task”来引用alloc或顶层任务(在alloc之外的)和“job”来引用一个作业或alloc集。
2.5 优先级,配额和接纳控制
当更多的工作出现而超过可容纳的限度时会发生什么?我们的解决方案是优先级和配额。
每个作业都有一个优先级,它是一个小的正整数。高优先级任务可以以牺牲低优先级任务为代价而获得资源,即使这导致抢占(杀死)后者。Borg将不同种类的作业分为不同的领域,并给每个领域定义了不重叠的优先权重,这些作业组包括:监视作业,生产作业,批处理作业和尽力而为的作业(已知的包括测试程序),他们的优先级依次递减。对于本文,prod作业是监测和生产领域的工作。
虽然被抢占的任务通常将被重新安排在单元中的其他地方,抢占级联可能发生,如果高优先级的任务碰到一个略低优先级的任务,而这个略低优先级任务又引发另一个略低优先级的任务,等等。为了消除大部分这种情况,我们不允许生产领域中的任务相互抢占。
细粒度优先级在其他情况下仍然有用 - 例如,MapReduce主任务以比他们控制的workers更高的优先级运行,来提高其可靠性。
优先级表示单元中正在运行或正等待运行的作业的相对重要性。
配额用于决定允许进行调度的作业。 配额表示为在给定优先级上的一段时间(通常为几个月)内的资源量(CPU,RAM,磁盘等)的向量。
数量指定用户的作业请求可以一次请求的资源的最大量(例如,“从现在直到7月底在单元xx中的prod优先级的20TiBRAM“)。
配额检查是许可控制的一部分,而不是调度:配额不足的作业立即拒绝提交。
较高优先级配额的成本高于较低优先级配额。生产优先级配额仅限于单元中可用的实际资源,因此,提交符合配额的生产优先级作业的用户可以预期运行。
即使我们鼓励用户购买的配额不超过他们的需求,但是许多用户仍然过度购买,因为这帮助他们在应用程序的用户群增长时克服不足。我们通过在较低优先级别上过度销售配额来响应这一点:每个用户具有在优先级零的无限配额,尽管这常常难以执行,因为资源被过度订阅。一个低优先级作业可能被允许了,但是由于资源不足而保持等待(未调度)。