如何在云中运行计算密集型任务?前沿技术
公有云的出现将大规模的HPC资源带到了普通公司的身边。在很多情况下,尤其是对于临时性HPC项目来说,和内部购买必要的计算资源相比,云解决方案在成本上更加行之有效。在公有云出现之前,只有少数公司,比如大型金融服务公司才有经费购买进行高性能计算所必需的资源。
在去年,可以看到在市场上有相当多的顾客需求,很多行业的许多公司针对大规模的HPC集群对软件平台进行测试。当我们首先向传统的HPC供应商描述需求时,经常被问到是哪个行业财团或是政府机关在谋求进行此项工作,因为这关系到HPC环境的规模。当我们告诉他们这是针对个体公司而非大型组织机构时,我们遭到了对方善意的质疑。最后,我们决定亲自构建集群软件,目标是能够在公有云和私有云上运行该集群软件。
当开发软件面对众多的商业和开源选择时,我们发现多数选项都针对同时运行在集群上不同的通用应用进行了优化。为了适应这类需求,集群依据安装在单个计算节点上不同的操作系统进行了硬分区,而且不管应用实际上需要多少计算资源,每台机器都提前预留给了特定的应用。这导致了计算资源的利用率相当低,平均利用率只有30%左右。对于想创建HPC集群并作为一般资源然后将其租用给公众使用的人来说,这绰绰有余。然而,这却不是满足典型的商业用户需求的最佳策略。
HPC 解决方案
我们决定基于不同的原则构建HPC软件。最初由对该解决方案极为感兴趣的某些用户从事该项目。这类用户寻求降低成本并缩短时间。完成这项工作他们不想花费超过一百万美元,而且如果花费数周才能得到结果,那么他们也会认为该解决方案将不会在对应的市场上具有竞争力。
当和使用HPC资源的用户进行交流时,我们注意到公司通常围绕一个通用的计算平台构建单一的HPC应用,或者是相关应用的集合,而且这些用户都希望能够拥有一个能够将计算时间最小化并将可用资源的使用率最大化的软件平台。
HPC集群设计的不同之处在于围绕一个原则,那就是能够动态编排单个核以确保最大化资源的利用率。集群运行单个计算平台并处理来自单个供应商的相关需求。这考虑到了宽松的安全模型,而且来自不同计算任务的代码能够共享操作系统,允许我们近乎实时地在工作任务之间切换核心。
该集群设计用来解决HPC领域相关问题的一个子集,而不是试图构建一个通用的,无所不包的计算解决方案。我们选择处理的问题的子集从本质上说是高度并行。单个计算需求的计算时间至少要比分发时间高一个数量级,而且问题集合和解决方案结果足够小能够在网络拓扑中有效地传输而且分发时间要比整个任务的运行时间低上几个数量级。集群软件被设计为在代码级别整合进计算密集型应用中,而不是提供一系列通用的远程接口。
集群架构
该集群设计用来将工作任务划分为多个计算任务,在可用的硬件资源上高效率地执行计算任务,并将计算结果返回给客户端应用。该集群对裸机,运行在OpenStack的私有云以及公有云有效。不同的部署场景被设计用来解决一系列的可用资源问题。当用户能够支付为单个应用分配固定计算资源的费用时,裸机是最有效的。私有云能够很好地应用于在应用程序之间分配公司内部硬件资源的场景,而且很容易部署一个不同的计算节点或者将HPC集群可用的计算资源转移给其他需要计算资源的请求。当突发的负载级别以及临时的需求使购买硬件变得不切实际时,公有云就是一个很好的部署场景。
HPC软件使用Apache Libcloud在多个硬件平台之间进行部署。我们已经成为Libcloud项目的主要贡献者,而且已经在很多软件项目中使用了Libcloud项目。HPC软件的顶层是HPC集群组件:调度程序,工作任务接口节点,通信交换架构以及计算节点,用于高效率地控制工作任务的执行。
组件
通信交换架构由一组RabbitMQ节点构成。为方便重新配置以及状态信息,单个实例被分配给控制面板或者是数据面板,数据面板用来将任务传送给计算节点并接收结果。没有聚合RabbitMQ实例因为我们发现这会严重降低客户端重新连接的速度。相反,客户通信库用于在相关的RabbitMQ实例之间分配请求,这提供了有效的可扩展机制。通常情况下问题以及结果有效负载在带内发送。然而,为了增强RabbitMQ针对大型有效负载的可扩展性,已经预先部署了分布式缓存集群。分布式缓存配置的优势在于问题集合大于几十KB,单个任务解决方案集合大于数百KB。
调度程序用来给单个计算任务分配计算资源。调度程序由一系列消息队列和不同RabbitMQ实例的结果交付构成,它通过控制面板通知计算节点的一个子集加入到队列中。调度程序是一个复杂策略的集合,允许客户为不同的用户预留计算资源,并说明资源失败的原因,而且还处理需要特定硬件比如GPU(GPU可能会出现在节点的子集当中)的工作任务。当集群地理位置相对接近,考虑到低延迟通信,调度决策的速率是100-200毫秒。
工作任务接口节点通过REST和WSDL接口提供了在集群中提交任务并检索结果的方法。通过重新提交失败的任务,工作任务接口节点提供了冗余性。工作任务通过数据面板通信交换架构提交给计算节点。在计算节点上客户端应用代码能够将工作任务划分为计算任务并提交给由调度程序所构建的工作任务队列,或者通过一系列的步骤继续划分为子任务。使用HPC资源进行工作任务分解为计算成本昂贵的工作步骤在很短的时间内完成提供了可能。最终用户提供的客户端代码经过优化以最有效的方式被分解为各种任务类型,经由类库集合和经过良好定义的API通过HPC软件的接口。分解链条和结果积累是相反的,直到最终的结果集合被分发给接口主机供客户获取。工作任务链中的组件控制了任务并行程度而且可以告知资源需求的时间表,如果策略允许的话,调度程序可以转移预先保留但未被充分使用的资源给其他的任务。
计算节点从指定的消息队列取出单个任务,获取任务执行所必须的带外数据,而且可以进行最终的计算或者将任务分解为其他任务,重新提交回队列中。实际的计算软件由客户端应用提供并通过编排层分发给单个节点。计算节点监控分配给单个工作任务队列的核心的使用率,如果分配的队列空闲比较久或策略控制超时,计算节点将从其他的队列抓取任务。累积的计算结果将返回给结果队列或者上载至分布式缓存集群并通过数据面板进行通知。
性能
总体设计的结果就是从单个任务到数百个并行任务,硬件资源的使用率都大大提高了。只要工作任务分解导致大量的并发任务多于总的可用计算核心,硬件资源的使用率达到95%是有可能的。
安全性
对公有云的安全性考虑是通过对连接到通信互联架构的类库中的可选的有效负载加密以及限制节点通过分布式防火墙访问实现的。
结论
在开始安装时,我们发现该解决方案显著减少了常规时间,非常重要的工作在任务时间表上消除了数个星期。正式由于我们所做的工作,该集群令人注目,很多公司已经准备部署了。通过将之前在本地硬件上花费一个月完成的工作整合到云中后只需要运行三个小时,公司不仅降低了成本而且建立了新的竞争优势,而且帮助他们更好、更快地服务客户。
最后的内容和公有云vs.私有云有关。很多厂商都提供了高密度,低成本的计算刀片,按照每个核心集群的成本是1万美元,那么总的费用是400万美元,粗略计算使用亚马逊的成本是6万美元/月,尽管通过预订或者按需购买成本可能更低。然而,通常来讲,如果你需要持续使用计算资源,那么和购买硬件的成本相比,在一年之内你可能要给亚马逊支付更多的费用。
然而,对于突发的、高度可扩展计算问题,对许多公司来说,在云中运行计算密集型任务是一个相当棒的而且能够支付得起的替代选择。