导语:本文以资源分配理念:拍卖、预算、抢占出发,引出Borg、Omega、Mesos、Kubernetes架构、数据、API的特点比较。然后梳理资源共享各种不同共享形式的内容,接着对比任务类型,最后回到资源利用率和基于数据预测角度,看相关系统是如何运用的和实现各自场景目标的。最后给出阿里巴巴电商在线服务资源调度器Zeus关键技术内容。
需要指出的是,进入这个领域的门槛不在具体某个技术,而业务场景和技术选型的映射匹配,特别是周边系统的完善程度,决定了如何选择方案、如何制定落地计划。整篇文章不是为了全面分析某个调度器,也不是全面对比某个关键点在不同调度器之间特色,而是以作者经验理解,在一个新场景下,如果需要设计或者完善一个资源调度器,那么,应该梳理那些关键场景和需求。选择性地从已有调度器系统吸取架构或模块经验,最低成本实现贴合自身业务场景的资源调度器。例如吸取调度器二层架构模式、数据集中管理方式、统一RestFullAPI、资源分时共享策略、在离线任务类型抽象等。
本文避免讨论生态,因为太过庞大,超出本文的主题。
关键词:资源调度器BorgOmegaMesosKubernetesZeus
以下是正文:
1.资源分配理念看已有调度器
在资源调度器中,资源分配理念:拍卖、预算或抢占,往往是混合运用。资源分配理念,折射出了资源调度器所在的生态系统或者说周边配合系统的成熟度、运行习惯。例如,Google从最早的广告拍卖机制起,拍卖的理念在Google内部就形成了一种经验、选择的爱好或者内部的默契,那么资源竞拍被分配出来的结果,大家很容易达成一致、理解。而国内企业,往往是预算驱动,周边系统的运行习惯,更趋向预算、采购,谁预算谁使用。这种环境下,资源被谁使用基本可以预见,成本也是比较容易找到归属者。在拍卖机制下资源抢占,初始分配是不大会发生,只有在运行时发生资源不够用的时候出现,低优先级的任务被Kill。在预算机制下,资源分配初期、运行时过程中,都会发生抢占。不同哪种分配背后共同追求的资源流动性是一致的。拍卖的另外一种好处是便于资源流动起来,不仅是资源利用率提升,更是资源投入产出比的最大化。而预算往往是一次性的,重点业务资源优先保障,使得适应性、灵活性、激励业务效率提升变得不如拍卖。
不同策略落地在架构、数据、API层面有着非常多的共同之处。从中不难发现Borg是始祖,后来的Mesos、Omega、Kubernetes、Zeus等都延续着Borg的某些重要特征,而又随技术发展,引入新的特征。针对每个系统的具体分析,可以参照Google、Baidu上通过关键词查询出来的相关文章或者各系统发表过的论文及官方文档[1,2,3,4,5,6,7]。
1.1架构层面
Borg
调度器架构图如图1所示[2],是Google建造的一个主控制核心,管理公司所有的数据库。两级优先级:服务性的高优先级和批处理的低优先级。两阶段调度:找到可行的节点,然后为最终放置对这些节点评分。
图1Borg架构图
Borglet向Master汇报状态,从而master确认borglet是否存活,以及是否需要执行Borglet上的任务迁移等操作。任务、资源的状态数据更新是周期性的,而不是变化通知机制。
Job使用BCL来描述,通过RPC命令tool提交到Borgmaster。Borg大量的调度任务属于Jobs,但是集群70%左右的CPU是给service的。
Borg一层框架,在框架上跑Schedule。框架是Borglet和BorgMaster之间进行状态通信,确保资源存活性、任务运行时数据收集,同时PAXOS协议,确保多master数据一致性,支持并发和容灾。而Schedule与BorgMaster进行数据读写,实现资源的分配和回收管理等。
Mesos
Twitter研发的超级网络系统,Mesos的出现比YARN早,引入两级调度的理念。两级调度通过一个名为资源邀约的新API发起,邀约是有时间限制的,激励应用程序去实现快速地调度。Mesos[3]里面并没有拍卖的影子,更注重公平性,允许短任务预留一些资源。时间期限就是资源的共享的生命周期。在Mesos中,资源邀约是悲观的或独占的。如果资源已经提供给一个应用程序,同样的资源将不能提供给另一个应用程序,直到邀约超时。
Borg和Mesos并不只是能让他们的服务器群智能化处理他们的数据,他们还让管理集群就像操作一台机器一样处理所有的数据[7]。
Omega
重点在介绍基于状态的资源管理组件,Omega[4]的资源管理器基本上,只是一个记录每个节点状态的关系数据库,使用不同类型的乐观并发控制解决冲突。这样的好处是大大增加了调度器的性能(完全并行)和更好的利用率。
Omega采取多版本控制的、乐观锁机制在遇到偶尔的资源冲突时候。所有资源状态存储在基于PAXOS协议实现的事物系统中,外部调度器访问并执行资源调度。
Kubernetes
作为Docker生态圈中重要一员,由Google开源,整个设计重点之一在于方便分布式复杂应用的部署和管理[5,6]。Kubernetes吸收了Borg使用过程中大量的实践经验,当然整个系统因为涵盖的功能较多,延续Borg完备、复杂性,相对Mesos等稍微简单些。Kubernetes面向云端,需要考虑的功能点非常多。例如网络、负载均衡、资源管理、高可用、镜像更新、存储、安全、监控等。Kubernetes架构如图2所示。
图2Kubernetes架构图
总结:主动、定时汇报的框架,还是变更通知的框架比较适合呢?状态基于PAXOS协议分布式事务一致性,还是集中数据库存储基于实践的成本、简单性、阶段目标出发,变更通知和数据库可以精简系统、快速搭建原型。如果要应对百万级服务器,那么PAXOS协议、定时汇报应该就是标配的技术方案了。通知模式,消息重发(发的频率、次数)、消息处理(脏数据、临界数据)、数据补偿等需要仔细设计,避免时不时的消息数据错误导致资源使用不一致,引发后续解救。PAXOS协议脑裂是一个潜在的风险,但是,相对通知模式还是显得优雅和透明些。
两级调度:第一级选择机器(也就是业务编排),第二级分配容器资源。或者第一级选资源,第二级业务编排组织。这个过程,局部最优可以加速资源调度性能,全局最优可以获取最佳的资源位。具体场景具体选择,并且都可以作为参数传入调度器。
两种或多种优先级:高优先级、低优先级,分别对应在线服务、监控服务、运维服务,离线短周期Jobs、批量Jobs等。业务优先级的定义和变更,需要业务层面全局的评估和系统自动化更新,并及时反馈到调度器中。业务方都趋向把自己的业务定位高优先级。确定不可抢占业务。
并发支持的程度和粒度,面向链路也就是队列,还是面向资源状态。每次申请资源全局最优还是局部最优,一旦发生冲突,乐观锁还是悲观锁。实践经验,先解决业务需求,求得生存,然后优化性能。
在整个架构之外,模拟器也是非常重要的子系统。尤其是资源调度器这种基础的服务系统,资源一旦分配错误或者不可用,造成的影响非常大。整个结构友好的支持模拟数据进行算法验证必不可少。总是假设,容器技术、生态的其他产品都是可信赖、高可用、跨语言API服务的。
1.2数据层面
Borg
在Google已经运行了10多年,是一个效率极高的系统。典型的Borgmaster使用10至14个内核和50GB内存,数据主要集中在内存。1分钟启停1万个task进程。99%的WebUI响应时间小于1s,95%的pollingborglet时间小于10s。针对成千上万节点,每分钟调度的速率为10K任务。典型调度时间是25秒左右(这依赖于具体节点的本地化。下载二进制占这个时长的80%,Torrent和树协议用于分发二进制文件)。单个cell内部98%机器都是混跑(prod/non-prod,long-runningservice/batchjobs),整个Borg系统中83%的机器是混跑。意味着Google资源共享不是简单的固定配额共享,又或者整机交付的共享,而是实时动态的共享。
在混部CPI方面,增加作业会导致其他作业进程CPI增加0.3%(CPI越大表示程序执行越慢),机器CPU使用率每增加10%会导致作业进程CPI增加2%。混跑集群平均CPI1.58,专用集群1.53。另外Borglet的CPI:混跑1.43,专用1.20。结论:CPI差别不大,因此混跑并不会显著的降低程序运行时间!
资源利用率主要的度量指标是单元压缩。也就是一个业务单元使用的资源最小化程度。一个典型的cell中,prod作业调度占70%CPU,55%Memory,实际使用占60%CPU,85%Memory。通过Borglet的周期性、实时计算,调整资源实例的配额,从而进行资源压缩。配置或者Jobs调度参数等都以JSON或者YAML格式实现。
Google的效率,从Google一个PE可以运维上万台服务器,可见相当先进了。
成本计费方面:将Job的提交、配置、具体每个task的资源使用情况都保存到一个数据库中,并提交SQL查询,供计费、debug、错误分析、容量规划。
Mesos