论文《Large-scale cluster management at Google with Borg》
简介
google的borg系统通过合理进行准入管理,高效的任务打包,多次提交和进程级隔离的资源共享来达到资源的高利用率。
它支持高可用应用来缩短运行时的故障恢复时间,同时它的调度策略可以减少故障发生的概率。
borg通过提供特定的声明性任务编程语言,名称服务集成,实时的任务监控和分析及模拟系统行为的工具来简化用户的l使用流程。
Borg解决的问题
大规模系统的资源调度,高资源利用率、高可用的解决方案
Borg解决以上问题的方法
大规模
- 任务分类。borg将工作负载分为了long-running和batch jobs两种,前者一般不会停止服务,后者则服务时间较短即可结束。
- 划分优先级。borg将高优先级的作业称为“生产型作业”(prod),将其他作业称为“非生产型作业”(non-prod)。大部分长时间运行的服务都是生产型作业,生产型作业被分配了大约70%的CPU资源并占用了大约60%的利用率;同时被分配了大约55%的内存资源并占用了大约85%的内存利用率。
- 集群。对于大规模系统,google将物理资源以每10K左右的机器作为一个cell,并将资源以cell为单位进行管理。
- 分解任务。borg将job分解为多个task,每个task都记录着它所属于的job,job也记录着task的信息。从而用户可以轻易管理任何一个job的任何task。
资源调度
- 使用alloc。alloc是为了task的预留资源,以便新的task产生时快速分配资源。同时还有alloc set对应于job
- 优先级。每个作业都有一个整数优先级。Borg定义的几个优先级包括:monitoring, production, batch, and best effort (also known as testing or free)。生产型作业(prod job)包含前两种优先级。高优先级的作业如果资源不够可以杀死低优先级的作业来抢占资源。但是为了避免“抢占洪流”,Borg只允许生产型作业抢占非生产型作业。
- 资源配额和准入控制。Quota是一组资源量化表达式(CPU、RAM、Disk等),它与一个优先级和一个时间段对应。如果Quota不足,作业提交会被拒绝。
高可用
** borg的命名与监控机制 **
Borg创建了一个稳定的Borg名字服务(BNS),用于为每个任务命名。任务名字包括cell name、job name和task number这个三元组。Borg将任务的主机名和端口号写入Chubby中的一致性、高可用文件。Borg也会将作业规模和任务健康信息写入Chubby,负载均衡器LoadBalancer据此来进行路由。
每个任务会构建HTTP server来发布其健康信息和性能指标,Borg根据URL来监控任务,并重启异常任务。
同时Borg还使用以下方法优化了监控方式
- 分数缓存。直到任务变化才会重新测量
- 等价类。大量相同task只需测量一个task即可
- 随机策略。全部测量十分耗费资源,可以采用抽样的方式进行检测。
** borg的优化 **
- 自动重现调度被驱逐的任务
- 将任务分散在不同的失败域中以降低相关失败
- 限制一个作业中任务的个数和中断率
- 使用声明性的期望状态表示和幂等变异操作,以便失败的客户端可以无害地重新提交任何被遗忘的请求
- 限制任务重调度速率,因为不能区分大规模机器故障和网络分区
- 避免引发错误的任务-机器配对 关键数据持久化,写入磁盘
资源利用率
- 混合部署。根据实验表明混合部署的资源利用率比独立部署要高。
- cell sharing。处理单元共享
- large cell。大处理单元
- fine-grained resource requests。细粒度资源请求
- resource reclamation。实际申请总是倾向于多于实际需要,因此时常会有资源闲置,可以利用这部分资源。
- 隔离。性能隔离的同时还要安全上的隔离。前者是用cgroup,后者则使用linux chroot实现。
一些思考
- naming机制在系统中非常重要。比如在该系统中将10k左右的物理机重新定义为cell,将任务分为job,task等,正如cse课上的系统思想。在大规模的系统中命名机制往往很重要。
- 有时在大规模系统中可以为了性能而舍弃虚拟化
- 这种完善的资源调度机制给了我很大启发,设定优先级,资源配额和准入机制等可以使资源让最有用的task来使用,也大大提升了容错率。
- 监控系统的启发。对于这样的大型系统,监控体系在完善的同时还可以利用缓存,抽样等方式提速是非常厉害的
- 最后感觉杀死低优先级进程或许还有优化的可能,如果还可以继续优化那么可用性还可以进一步提升。