google服务器集群的管理系统,相似于百度的Matrix,阿里的fuxi,腾讯的台风平台等等,还有开源的mesos java
Borg provides three main benefits: it c++
borg主要面向于系统管理员和google开发者,这些用户在borg上面运行他们的服务和应用程序,用户以job的形式提交任务,每一个job包含一个或者多个tasks,每一个job运行在一个cell里,cell是机器的集合,能够理解为是一个逻辑的IDC web
borg上运行的服务一般能够分为两类: 算法
这两种不通类型的任务在borg的cell里一般是混部的,同时又须要结合不一样类型任务的特色,以及IDC属性,等等作出不一样的调度策略。例如end- user-facing服务利用率一般都会有一个固定的模式,白天的时候利用率很高,晚上机器又很闲,深夜可能几乎没什么访问量等等,另外Batch型任 务执行时间段,通常上来跑个几分钟,几小时就完成任务了。等等。 服务器
borg最主要的目的,就是要提升机器的利用率。 网络
在google内部,不少应用程序框架都是构建在borg之上的,例如mapreduce系统,FlumeJava,Millwheel,Pregel, 还有google的分布式存储服务,例如GFS,Bigtable,Megastore。像mapreduce,flumejava这种服 务,master和他们的job都是跑在borg上的,这里的master和job区别于borg里的master和job 架构
In a representative cell, prod jobs are allocated about 70% of the total CPU resources and represent about 60% of the total CPU usage; they are allocated about 55% of the total memory and represent about 85% of the total memory usage. 并发
数据中心 > 集群 > cell app
A cluster usually hosts one large cell and may have a few smaller-scale test or special-purpose cells. We assiduously avoid any single point of failure. 中等规模的cell大约10k台服务器左右,不包括测试cell,个人理解这些smaller-scale test cell的主要做用是小流量专用?每一个机器上可供调度的资源类型包括:cpu,内存,网络,磁盘,甚至是处理器性能,类型,以及ssd,ip地址等等(我 的理解,对于某些类型的服务,是须要固定IP,而不容许随意调度,例如存储系统)。 负载均衡
用户在提交job的时候申请资源,而后borg将它们调度到某机器上执行,监控他们的状态,若是有必要在job的状态failed后重启它们
job的属性包括:名称,owner,tasks,同时还包括一些调度的约束条件,例如处理器架构,os版本,ip地址等等,这些会影响borg-master调度的结果,固然这些条件不必定是强制约束的,分hard和soft两种。
一个job只能跑在一个cell里,每一个job会有N个task,每一个task运行期间会有多个进程,google并无使用虚拟机的方式来进行task之间的资源隔离,而是使用轻量级的容器技术cgroup。
task也有本身的属性:资源需求和一个index,大部分时候一个job里的全部task的资源需求都是同样的。
Users operate on jobs by issuing remote procedure calls (RPCs) to Borg, most commonly from a command-line tool, other Borg jobs, or our monitoring systems
job是经过一个google本身实现的BCL语言来描述的,用户能够经过update的方式来更新job的描述文件,基于过程状态机:
update过程是轻量的,非原子的,并且也是有可能会失败的,Updates are generally done in a rolling fashion, and a limit can be imposed on the number of task disruptions (reschedules or preemptions) an update causes; any changes that would cause more disruptions are skipped
alloc的本质上就是如今的容器,用来运行一个或者多个task,是task的运行环境,是一组资源的描述。只要是alloc里的资源,无论有没有使 用,都是已经分配了的(不容许给Batch类型的任务使用)。不过google也提到这个alloc是能够并发使用,也能够是重复利用的,并发的意思是说 多个task能够同时跑在一个alloc里,重复利用的意思是说一个task跑完了能够继续分配给另一个task使用。
并发使用能够举个例子:有两个Job,一个job是web server实例,另外一个job是相关的一些task,例如日志收集等等,这两个job的task能够同时跑在一个alloc里,这样日志收集模块能够将 web server的日志从local disk传输到分布式文件系统里。
一般一个task会关联一个alloc,一个job会关联一个alloc set
每一个task都会有一个优先级,高优先级的task能够抢占低优先级的task的资源,优先级是一个正整数,borg里将这些优先级分红4类:monitoring, production, batch, and best eort
若是一个task被抢占了,一般会调度到别的机器上继续运行(同一个cell),we disallow tasks in the production priority band to preempt one another (单指production级别的仍是平级的job都不能相互抢占?)
优先级肯定是否抢占,quota决定是否能够调度,quota表示所须要的资源,例如cpu,内存,网络带宽,磁盘配额等等
高优先级的task一般会比低优先级的task须要更多的quota,用户申请资源的时候建议申请的比实际的资源占用高一些,以确保task不会由于超发而被kill掉,特别是内存。另外,多申请些资源也能够应对流量突发的状况。
优先级0能够有无穷大的quota,但一般会由于资源不足处于PENDING状态而得不到调度
仅仅建立和调度task运行是不够的,从服务的角度来讲,还须要有一个服务自动发现的机制,调度须要对用户透明,作到用户无感知。borg的Borg name service(BNS)就是为了解决这个问题的。
borg为每一个task建立一个BNS名字:cell名 + job名 + task索引,BNS名字和task的hostname + port会被持久化到chubby上,经过DNS解析,用户凭BNS名字就能找到task,另外,Job的task数量和每一个task的健康状态也会更新 到chubby上,这么作的目的主要是为了服务(这里的服务是指job自己,多是个web server,也多是个分布式存储系统等等)的高可用,对用户请求作负载均衡。
每一个task都会有一个内置的http服务,暴漏一些task的健康信息和各类性能指标,例如rpc时延等等。borg经过监控某个特定的url来决定task是否正常,若是不正常,好比http返回错误码等,就重启task。
google还有一个叫sigma的系统,用户经过web界面就能够直观的观察到用户本身全部的job,cell状态,甚至是task的健康信息,资源利 用率,日志,状态变动历史等等。日志是rotated的,避免打飞磁盘,另外,为了调试方便,即便task运行结束后,log也会保留一段时间。
If a job is not running Borg provides a “why pending?” annotation, together with guidance on how to modify the job’s resource requests to better fit the cell. We publish guidelines for “conforming” resource shapes that are likely to schedule easily.
每一个cell,包含一个控制器,borgmaster,同时cell里的每一个机器,都运行着一个叫borglet的agent程序,无论是master和agent,都是用c++写的
每一个master包含两个进程,一个主进程,一个调度进程,主进程处理用户请求,例如建立job,查询job等等,It also manages state machines for all of the objects in the system (machines, tasks, allocs, etc.), communicates with the Borglets, and offers a web UI as a backup to Sigma.
master有5个副本,每一个副本维护一份整个cell状态的内存拷贝,并持久化到一个 highly-available, distributed, Paxos-based store 的本地磁盘上。经过paxos选出一个leader,负责处理cell状态变动的全部请求,例如用户提交一个job,中止一个job等。若是leader 宕机以后,chubby会选举出另一个leader来提供服务,整个过程大概须要10s左右,若是cell规模很大,这个时间可能会持续到1分钟。
master会按期checkpoint,snapshot + change log,这样能够将borgmaster恢复到以往任意的一个时间点,fixing it by hand in extremis; building a persistent log of events for future queries; and offline simulations.
TODO: Fauxmaster
当用户提交一个job时,borgmaster会将job的元数据存储到一个基于paxos的存储系统里,同时将job的task放到pending队 列,如上面咱们提到的master架构,这个队列会被另一个调度器进程按期异步地扫描,调度器进程一旦发现某个机器可以知足task的运行条件(例如资 源是否足够,是否符合某些特定约束,处理器架构,内核版本等等),就将task调度到改机器上运行(注意:调度器调度的对象是task而不是job)
The scan proceeds from high to low priority, modulated by a round-robin scheme within a priority to ensure fairness across users and avoid head-of-line blocking behind a large job.
调度算法包括两部分:
在feasibility checking阶段,调度器检查机器是否知足job的约束条件以及是否有足够的可用资源(包括已经分配给低优先级job的资源,这些资源是能够被抢占的)。这里可用资源的定义是:
在scoring阶段,对机器进行打分,挑选出最合适的一个机器运行task,打分机制:
打分模型主要有两种:
borg目前使用的是介于worst fit和best fit之间的一个变种:hybrid,尽量的减小闲置资源。
若是打分后选择出来的机器可用资源不足,那么抢占就会发生,低优先级的做业首先会被踢掉,直到有足够的空闲资源为止。被抢占的做业从新回到borgmaster的PENDING队列里等待迁移(若是得不到资源也有饿死的可能)。
因为大部分包都是不会被修改的,因此borg在调度的时候还有一些优化的策略,为了减小每次部署时下载包的时间(平均25s左右),borg在调度时会优先选择那些已经存在这个包的机器。(因为包不多被修改的特性,包是能够被cache的)
borglet是borg运行在单机上的agent程序,borglet的职责以下:
borgmaster会按期轮询全部的borglet,收集处理全部任务的运行状态。master连agent的好处是有利于master控制负载,也有大部分分布式系统是agent去连master的,好处是master的异常处理逻辑相对简单。
前面咱们提到master是多副本的,leader负责向agent发送心跳,并根据agent的返回结果更新master的状态,为了提升性能,心跳的 内容可能会被压缩,只传输diff。另外,若是一个borglet长期不响应master的心跳,则master会认为该机器已经宕机,而且这机器上的所 有task都会被从新调度。若是borglet忽然恢复,则master会让该机器kill掉全部的task。
master宕机并不影响borglet以及正在运行的task,另外,borglet进程挂了也是不影响正在运行的task的。
在google里,平均每一个borgmaster须要管理数千台机器(前面咱们提过,一个中等规模的cell大约是1w台服务器左右),有些cell每分 钟提交的任务数就超过1w个,一个繁忙的borgmaster甚至能够用到10-14核,超过50G的内存。那么google如何解决集群规模不断扩展带 来的可扩展性问题呢?
早期的borgmaster只有一个简单的,同步的循环过程:
为了解决大集群,borgmaster分离出一个调度进程,两个进程并行协做,固然,灾备是有的。
分离出来的调度进程职责是:
这个过程和Omega里的乐观并发控制精神是一致的,borg最近还新增了一个feature,针对不一样的workload类型使用不一样的调度器
此外,borg针对可扩展性还作了几个优化:
在一个大型的分布式系统里,单点故障是常态,运行在borg中的task,故障的缘由既多是机器宕机,也多是被抢占调度,下图是borg测试数据里发现的被抢占状况:
除了应用程序自身须要考虑容灾以外,borg在此方面也作了很多事情,来提升job的可用性: