在互联网用户和应用爆炸的今天,我们承载的服务和运算,无论在规模还是性能上都提出了前所未有的要求,开发人员常常偷偷在想,能不能给我一个超级计算机,很多问题就不再是问题了。然而,大家又都很清楚,出于成本的考虑,这也就是想想,就像我们有时候也幻想着自己变成超人一样。Gaia的出现,能够让应用开发者像使用一台超级计算机一样使用整个集群,让几万甚至几十万个核协同做一件事情,将所有资源化为一片云,而将这片云带给我们的风在哪里?
2014年刮起一阵最炫Docker风,掀起一股股热浪。在云计算和开源软件大行其道的今天,Docker的出现正好顺应了时代的发展,占尽了天时地利人和。在这里,我们和大家一起审视一下Docker,它能给我们带来什么价值,它是否真的无所不能。
我们将Docker带到大家面前时,很多人有两个疑虑?
第一. Docker看起来还不错,但是作为一个新东西,它靠谱么?我们总结一下Docker的技术栈,如图1,Docker=namespace+cgroups+aufs。大家知道,这些技术都不是最新才出现的,其中最核心cgroups在2007年就进入了Linux内核主版本。
图1. Docker技术栈
第二. Docker性能如何?运行在其中的进程会不会在性能上被打折?为了理解Docker,我们通常会将其认为是一种轻量虚拟机,然而用过虚拟机的人都会对其性能抛出疑惑?Docker的性能到底如何?我们给出业界比较认可的一份IBM在2014年7月发表的一份researchreport。
在解决了靠谱度和性能的两大疑虑之余,大家开始迫不及待的迎接和追捧Docker了。
1)Docker的出现将软件从开发方到使用方的交付过程变得集中化、标准化、透明化:
可以说Docker带来的最大价值在于降低了软件的交付成本。
2)Docker将容器技术带到更多人面前。
容器技术早在十年前就提出并被Google大规模使用,然而,一提到云计算,大家首先想到的大多还是虚拟机,container技术在Docker之前还没有进入到大多数人的视野。与虚拟机相比,Docker具有更多的优势:
由于Docker可以运行在任何有合理数据内核的Linux虚拟机上,所以它可以运行在很多IaaS提供的云上。许多大的云提供商宣布了对Docker和它的生态系统的附加支持。不但开源的mesos,kubernetes,Yarn等项目都开始大力支持Docker,Docker生态圈中又出现了一些新的项目,如Deis、Flynn等诸多平台和系统。很多做Docker和支持Docker的云平台的创业公司似乎也在一夜之间出现。在腾讯内部,各种系统,如CAE、TAF、Yard等等也都开始调研对Docker的支持。为何Docker这股风,催生了这么多云呢?根本上还是因为要更好的发挥Docker的优势,Docker必须和云平台结合。
• Docker可以寻找到更加适合的机器来运行,对于应用来说,真正做到了“Machinesare anonymous“;
• Docker可以以最大化资源利用率的方式运行,节约成本;
• Docker可以自动部署,无需人工参与;
• Docker不再受到机器故障的制约,可以自动“再生”,满血复活,因为Gaia会自动识别故障机器,自动迁移Docker到健康机器上;
• Docker可以实现智能化scaling决策;
• Docker畅游云端,充分利用云平台的大规模效应,服务于海量用户;
• ……
Gaia(盖亚)团队从2009年研究container以及云平台,目标是想在腾讯实现一个类似Google Borg的基础架构级平台。希望能让业务真正以云化的模式运行,在自动化运维、容灾容错、扩容缩容、提升分布式系统开发效率、智能资源调度等方面为业务创造更大的价值。
我们将平台的稳定性作为第一设计原则,因为Gaia作为一个通用的集群操作系统,服务于所有业务类型,底层的Gaia的稳定性就至关重要。为了实现平台的稳定性,我们通过下面几种具体原则实现:
1)任何环节无单点。
对于Gaia Master,我们部署了多个master,多个master之间进行leader选举,通过master内部状态的保存和恢复机制,保证master的HA;Etcd本身也是多个server的,采用Raft协议来保证一致性和可靠性;在分布式文件系统这里,几乎所有成熟的分布式文件系统都有HA模式,并且多副本的方式也保证了数据不会因为个别机器故障丢失;在实现Docker registry时,我们采用了registry server pool的方式,无状态的多个server互为备份,任何一个宕掉都不会影响服务;Gate、apiserver等模块也都有响应的HA方式部署,没有一个模块是单点。
2)内部错误都有重试。
对Gaia系统内部的异常,我们都会有自动重试,并且不会占用用户设置的retry_times和migrate_times次数。举几个简单例子,比如NM异常,Gaia会自动将上面的container迁移到其他可用节点上;比如docker registry或者etcd暂时异常,NM会自动重试;如果某一个NM上的docker环境问题,Application Master会自动找master要新的资源尝试再次启动……
3)简化底层,保持最小Core。
Gaia有很多功能,但是我们并不追求“大而全”,在耦合性控制方面控制严格,在最关键的Gaia master和NodeManager都保持最小功能集合,保证Gaia Core稳定性和功能的纯粹性。在架构上,master只管理到application级别,以及实现核心的schedule功能,而对于每一个container的监控,迁移,扩容,缩容等功能,全部放在外部的ApplicationMaster上,这种简化后的架构让我们获得了可靠性、可扩展性等方面的优势。
4)内、外部强监控。
Gaia的每一个组件,我们都有监控、报警,以及各种指标的采集,也有过载保护。同时,我们对于每个集群,也有模拟用户行为做的外部监控,上报集群可用性参数,一旦集群出现任何影响到用户的问题,永远是Gaia自己先发现。
大规模计算集群是很昂贵的,因此如何能更好的利用它们十分重要。通过在同一机器上运行一组不同的工作负载的作业可以提升集群的使用率和效率。这种整合降低了负载,但是它使调度问题更复杂,需要考虑多的要求和策略。同时,调度也按照集群规模大概成比例的增加,因此成为了可扩展性的瓶颈。
很多batch作业是短作业,其快速周转十分重要,因此一个轻巧的、低质量的方式,就可以使placement工作的很好。但是长期运行的,高优先级的service作业(其中20%-40%运行了一个多月)必须符合严格的可用性和性能指标,这意味着需要仔细布置任务,最大限度的容灾,以及提供良好的性能。调度器会尽量将task放在可以防止孤立和联系失败的地方,在几十个故障域的嵌套和重叠的情况下,这是一个NP难问题。Gaia的自研调度器Sfair,承受住了现网的压力,具有极强的可扩展性,现网单集群规模已达8k台;具有多业务多租户的调度能力,服务现网2500个资源池;在作业优先级、抢占、quota管理等方面积累了较多经验,保证了高优先级作业的资源。
在云平台环境下,Machine is anonymous,而端口也是一种resource,与此对应的,服务注册和发现就成了必要。
如图2,NM在启动Dockercontainer时,会将该Docker的真正地址,包括ip和所有的端口映射,都会通过etcd做自动的服务注册。对于Docker内部的服务,我们通过修改Docker源码,扩展了几个Gaia相关的环境变量,将IP以及端口映射传入。服务的注册和发现本质上一种名字服务,因此不难理解为什么在创建App的时候,让用户填一个App name的字段。而这种基于名字的服务是贯穿这个Gaia的过程的:在提交作业时,用户不需要指定Gaia master的地址,而是通过指定Gaia cluster的name即可;在app的地址时,也是通过app的名字获取;本质上port mapping也是一种名字,只不过是将用户原来expose的端口作为name,将实际端口作为value。
图2. Gaia的服务注册和发现
Docker目前主要管理了CPU和memory的管理,然而这两种机制都存在着一定的问题。基于share机制的CPU管理对部分服务类型的application,无法保证性能。而内存管理可能问题更大,hardlimit的管理策略,不但使用户进程容易被kill,更造成了资源的浪费,对用户估计自己业务的资源需求也非常高。为此Gaia在资源管理方面主要做了两个方面的优化:
业务提交作业时指定各个资源维度的配额,任务运行时可以临时超额使用资源,这些资源来自本机尚未分配的资源,或者已经分配给其他任务,但未被实际占用的资源。如果一个任务尚未用完其资源配额,它的资源请求总是被满足(当空闲资源不足以满足其资源请求时,强制夺回被其他任务借用的资源)。
例如,在内存管理方面,Gaia不使用hardlimit的策略,而是在基于cgroups 类型container中引入了EMC(Elastic Memory Control)的弹性内存管理机制,在EMC上线后,现网的oom事件显著减少。
图3. Gaia EMC
Docker在资源管理纬度方面只有CPU和memory两个维度,这对于共享的云环境下需要完善,也是目前相对于虚拟机不足的地方。Gaia已经引入了磁盘容量管理,正在开发网络出入带宽控制以及Disk IO的控制纬度。不但在Docker层做控制,还将其引进调度器,不但实现了资源的隔离,还要实现资源的保证。图4左边为没有隔离时两个任务无序竞争的情形,右图为启用了网络带宽隔离之后的情形。
图4 Gaia 网络入带宽控制
Docker的出现为Gaia平台接入在线service任务提供了一种更方便、更标准、更通用的方式。我们为了更好的服务公司内的在线业务,在Docker社区的基础上,实现了一些定制的功能。
1)Docker daemon热升级功能。截至社区Docker1.8.3版本,依然没有实现Docker的热升级功能,Docker daemon进程退出时会杀掉所有的container,会极大的影响Gaia云平台的高可用性。为此我们实现了Docker daemon的热升级功能,daemon启动container时,启动一个monitor进程监视用户进程的运行。daemon进程退出时,monitor进程托管给init进程,从而不对用户进程产生任何影响。
2) 固定IP的网络模式。Docker原生提供了Host/NAT两种网络模式,Host模式直接使用主机的网络模式,性能最高,但是在云环境下,由于没有网络隔离,不同业务的app端口容易冲突。NAT模式可以解决端口冲突问题,但是网络性能较差,并且container IP对外不可见。为此,我们实现了一种新的网络模式,为每一个container分配一个和主机同一网段的IP,性能比Host模式略差,而且对网络环境进行了隔离。
3)Docker RBD plugin。Ceph是一种为高性能、高可靠性和高可扩展性而设计的分布式的、统一的存储系统。传统云操作系统使用本地文件系统作为container的本地存储,当container发生跨机迁移时(节点宕机或者app kill后重新提交),存储的本地数据会丢失。对于本地存储有需求应用,这种数据丢失会造成比较大的数据恢复开销。为了解决这个问题,Gaia云操作系统使用ceph rbd作为container的本地存储。当发生跨机迁移时,container可以挂载原container使用的RBD,保证数据就不会丢失。
还有其他一些定制功能:NAT模式同主机Container间互相访问时,使用主机IP;Container访问控制,对container可以访问的ip进行限制。解决container中真实的资源显示问题,件让Docker像虚拟机般无缝对接公司网管监控,我们也积极的参与了社区开发,共贡献了30+个patch。
云平台的愿景是美好的,但同时也是理想化的。尤其是在腾讯内部的实际情况,业务都已经相对比较成熟,要迁移一个成熟的业务到云平台上,是需要一些接入成本的。未来,Gaia会进一步降低业务接入的门槛,提升系统易用性。
IEG研发管理部开发了自研游戏框架,并且将该开发框架开放给公司外部的游戏开发商,并且在腾讯运营这些游戏,称之为“游戏云”。由于是外部应用,处于安全的考虑,将支持游戏云的Gaia集群搭建在腾讯云上的虚拟主机上。
图5 游戏云 on Gaia
游戏云直接依托于Gaia建设,使得游戏云不必关注底层的资源管理以及调度、容灾、隔离、部署等等细节,大大缩短了游戏云的研发周期,并且由于使用了Gaia的资源共享,也节省了机器成本,详见图6。
图6 Docker on Gaia助力游戏云
GoingMerry On Gaia是基于Gaia搭建的GoingMerry平台的升级版,用于CVR特征工程相关的工作。作为特征选择平台,它把特征选择中所用到的功能封装成接口,以服务的形式提供给用户调用,使用方便;另外它搭建于docker/Gaia平台之上,实现了任务的动态调度,具有良好的稳定性和可扩展性。
用户在使用GoingMerry On Gaia做特征选择时,只需编写一个简单的脚本程序调用GoingMerry的接口,在接口参数中提供必要的信息,如文件路径、训练参数等,整个特征选择过程就可以自动完成。另外因为它基于docker/Gaia搭建,所以稳定性和可扩展性良好。当一台机器出现问题时,服务可以自动迁移到集群内其他机器上;当有临时的繁重计算任务时,可以很方便的扩容,增加服务的worker的数量,提供更大的计算容量。
下面通过一个例子,说明如何调用GoingMerry OnGaia接口进行特征选择。
假设我们有一批数据,想知道在CVR预估模型训练时,不同的参数配置下最优的特征子集合。在不借助GoingMerry的情况下,我们可能需要:
现在,有了GoingMerry,我们只用提供一些必要的信息,如:
路径信息: (训练数据)
/stage/u_isd_conversion/pcvr_pipeline/goingmerry_cpc/2015070*/part* (测试数据)
/stage/u_isd_conversion/pcvr_pipeline/goingmerry_cpc/20150710/part* (结果文件)
/stage/u_isd_conversion/GoingMerry/data/model
参数:要尝试的lambda值:0.3, 1.0, 3.0;要选出的特征数量:2
然后编写代码,调用接口(python):
Mariana是腾讯数据平台部的深度学习平台,详情请参考http://djt.qq.com/article/view/1231。没有Gaia的mariana作业要运行,用户在运行作业之前需要在一台或多台GPU机器上申请个人账号,然后按如下步骤操作:
按照上述方式运行作业可能会遇到以下问题:
1)GPU机器负载不均:部分机器上用户或运行的作业太多,导致不同用户或作业之间竞争GPU资源。与此同时,部分机器没有用户使用,导致GPU空闲。GPU机器负载不均会导致GPU使用率偏低,不能充分利用GPU资源。
2)无法达到最佳性能:多GPU系统有拓扑结构,使用拓扑上最接近的几颗GPU能使通信开销更小,能达到最佳性能。但用户将要使用哪些GPU是无法确定的,可能无法使用最佳的GPU组合,进而影响性能。
3)应用程序相互影响,速度变慢:不能隔离GPU、CPU、Memory等资源,使用户之间的应用程序相互影响,导致程序运行速度变慢或发生意外错误(如:内存不够会导致OOM)。
4)运行多机多GPU程序比较麻烦:一般情况下,运行多机多GPU程序能显著提高作业运行速度,但是这需要用户申请多台机器,同时也会遇到用户竞争GPU资源的问题。
在GPU云平台上运行作业:
图7 Docker on Gaia上提交APP
是的,就这么简单!
Gaia致力于简化开发人员的逻辑,让开发人员拥有一台自己的超级计算机。开发稳定的产品化Docker,让Docker和云在腾讯落地生根,提升公司的整体服务器利用率。让Gaia成为真正的“开发的云、平台的云、云的云”,为业务提供更多有价值的服务!