Skip to content

Latest commit

 

History

History
80 lines (61 loc) · 8.97 KB

File metadata and controls

80 lines (61 loc) · 8.97 KB

Borg

一、简介

定义:集群管理系统叫Borg,它管理、调度、开始、重启和监控谷歌运行的应用程序的生命周期。

  1. 对于用户:

    1. Borg的用户是谷歌开发人员和系统管理员(网站可靠性工程师 SRE),他们运行谷歌应用与服务。用户以job的方式提交他们的工作给Borg,job由一个或多个task组成,每个task含有同样的二进制程序。一个job在一个Borg的Cell里面跑,一个Cell是包括了多台机器的单元。这一节主要讲用户视角下的Borg系统。
    2. 用户可以在运行时改变一个job中的task的属性,通过推送一个新的job配置给Borg。 这个新的配置命令Borg更新task的规格。这就像是跑一个轻量级的,非原子性的事务,而且可以在提交后轻易再改回来。更新是滚动式的,在更新中可以限制task重启的数量,如果有太多task停掉,操作可以终止。
  2. 工作负载:

    1. 长期的服务:这种服务是面向终端用户的产品如Gmail、Google Docs、网页搜索,内部基础设施服务(例如,Bigtable)
    2. 批处理任务:需要几秒到几天来完成,对短期性能波动不敏感。
    • 在一个Cell上混合运行了这两种负载,取决于他们的主要租户

      (例:有些Cell就是专门用来跑密集的批处理任务的)

    • 工作负载也随着时间会产生变化:批处理任务做完就好,终端用户服务的负载是以每天为周期的。

    • Borg需要把这两种情况都处理好。

  3. 集群&Cell:

    • 一个Cell里面的所有机器都属于单个集群
      • 集群是由高性能的数据中心级别的光纤网络连接起来的。一个集群安装在数据中心的一座楼里面
      • n座楼合在一起成为一个site。
      • 一个集群通常包括一个大的Cell还有一些小的或测试性质的Cell。我们尽量避免任何单点故障。
    • 在测试的Cell之外,我们中等大小的Cell大概包括10000台机器;一些Cell还要大很多。
    • 一个Cell中的机器在很多方面都是异构的:大小(CPU、RAM、disk、network)、处理器类型、性能以及外部IP地址或flash存储。Borg隔离了这些差异,让用户单纯的选择用哪个Cell来跑任务,分配资源、安装程序和其它依赖、监控系统的健康并在故障时重启。
  4. Job&Task

    • Job:
      • 一个Borg的job的属性有:名字、拥有者和有多少个task。
      • job可以有一些约束,来指定这个job跑在什么架构的处理器、操作系统版本、是否有外部IP。
      • 约束可以是硬的或者软的。
      • 一个job可以指定在另一个job跑完后再开始。
      • 一个job只在一个Cell里面跑。
      • 用户通过RPC来操作Borg的job,大多是从命令行工具,或者从我们的监控系统。
      • 大多job描述文件是用一种申明式配置文件BCL -- GCL的一个变种,会产生一个protobuf文件。BCL有一些自己的关键字。GCL提供了lambda表达式来允许计算,这样就能让应用在环境里面调整自己的配置。上万个BCL配置文件超过一千行长,系统中累计跑了了千万行BCL。Borg的job配置很类似于Aurora配置文件。
    • Task:
      • 每个task包括了一组linux进程,跑在一台机器的一个容器内。大部分Borg的工作负载没有跑在虚拟机里面,因为我们不想付出虚拟化的代价。而且,Borg在设计的时候还没硬件虚拟化。
      • task也有一些属性,包括资源用量,在job中的排序。大多task的属性和job的通用task属性是一样的,也可以被覆盖,Borg程序都是静态编译的,这样在跑的环境下就没有依赖,这些程序都被打成一个包,包括二进制和数据文件,能被Borg安装起来。
      • 一些task更新,例如更新二进制程序,需要task重启;另外一些例如修改资源需求和限制会导致这个机器不适合跑现有的task,需要停止task再重新调度到别的机器上;还有一些例如修改优先级是可以不用重启或者移动task的。
      • task需要能够接受Unix的SIGTERM信号,在他们被强制发送SIGKILL之前,这样就有时间去做清理、保存状态、结束现有请求执行、拒绝新请求。实际的notice的delay bound。实践中,80%的task能正常处理终止信号。
  5. Allocs

    • Borg的alloc(allocation的缩写)是在单台机器上的一组保留的资源配额,用来让一个或更多的task跑;这些资源一直分配在那边,无论有没有被用。allocs可以被分配出来给未来的task,用来保持资源在停止一个task和重启这个task之间,用来聚集不同jobs的tasks到同一台机器上一个alloc的资源管理方式和一台机器上的资源管理方式是类似的;多个tasks在一个alloc上跑并共享资源。如果一个alloc必须被重新定位到其他的机器上,那么它的task也要跟着重新调度。
    • 一个alloc set就像一个job:它是一组allocs保留了多台机器上的资源。一旦alloc set被创建,一个或多个jobs就可以被提交进去跑。简而言之,我们会用task来表示一个alloc或者一个top-level task(一个alloc之外的),用job来表示一个job或者alloc set。
  6. 优先级、配额&管理控制

    当有超量的工作负载在运行的时候的解决方案是优先级和配额。

    • 优先级:所有job都有优先级,一个小的正整数。高优先级的task可以优先获取资源,即使后面被杀掉。Borg定义了不重叠的优先级段给不同任务用,包括(优先级降序):监控、生产、批任务、高性能(测试或免费)。优先级是jobs的相对重要性,决定了jobs在一个cell里面是跑还是等(pending)。
    • 配额:配额是用来决定jobs是否运行被调度。配额就是一组资源(CPU,RAM,disk)的数量在一个指定的优先级、一个指定的时间段(月这个量级)。数量决定了这个用户的job可以用的最多资源。配额检查是管理控制的一部分,不是调度层的:配额不足的任务在提交的时候就会被拒绝。
  7. 命名&监控

    • 命名:光是创建和部署task是不够的:一个服务的客户端和其他系统需要能找到它们,即使它换了个地方。为了搞定这一点,Borg创造了一个稳定的“Borg name Service”(BNS)名字给每个task,这个名字包括了cell名字,job名字,和task编号。
    • 监控:Borg记录所有的job提交和task时间,以及每task的资源使用细节在基础存储服务里面。这个存储服务有一个分布式的只读的SQL-like的交互式接口,通过Dremel提供出来。这些数据在实时使用、debug、系统查错和长期容量规划上都很有用。这些数据也是Google集群负载追踪的数据来源之一。

二、优点

  1. 隐藏资源管理和故障处理细节,使其用户可以专注于应用开发
  2. 高可靠性和高可用性的操作,并支持应用程序做到高可靠高可用
  3. 让我们在跨数以万计的机器上有效运行
  4. 辅助服务可以很容易置入下一个主任务

三、缺点

  1. 对于跟踪和管理来说,调度多作业的工作流程要比调度单一的作业更好。关于工作流组件,还需要更灵活的方式。解决办法是可以将任意的键值对附加到每个任务上,并允许用户对其进行查询
  2. 每台机器一个IP。这会导致一台机器上的端口冲突,以及复杂的绑定和服务发现。可以通过Linux的命名空间、IPv6和SDN来解决
  3. 复杂的规范语言。知识点太多,作为一个普通用户很难上手。自动化确定资源请求需要一些工作

四、My Comment

从2013年末以Docker为代表的容器技术的迅速兴起,容器技术的进化速度很快就将一个曾经并不需要被大多数开发人员关注的问题摆到了台面————我们应该如何高效地抽象和管理一个颇具规模的服务集群,这也是Borg全力阐述的核心问题。
同大多数云平台类项目宣称的口号一样,Borg最基本的出发点还是“希望能让开发者最大可能地把精力集中在业务开发上”,不需要关心这些代码制品的部署细节。然而另一方面,Borg非常强调如何对一个大规模的服务器集群做出合理的抽象,使开发者可以方便地管理自己的所有任务。
此外,Borg强调的是规模。Google内部跑在Borg上的作业数量、以及被Borg托管的机器数量是非常庞大的。例如我们Borg一个Medium的计算单元就等价于10K个机器的规模。
Borg里服务器的划分如下: Site = 一组数据中心(Cluster), Cluster = 一组计算单元(Cell), Cell = 一组机器。 其中计算单元(Cell)是最常用的集群类别。