走近伏羲,谈5000节点集群调度与性能优化

author author     2022-08-24     326

关键词:

5K项目是飞天平台的里程碑,系统在规模、性能和容错方面都得到了飞跃式的发展,达到世界领先水平。伏羲作为飞天平台的分布式调度系统,能支持单集群5000节点,并发运行10000作业,30分钟完成100TB数据Terasort,性能是当时Yahoo ! 在Sort Benchmark上世界纪录的两倍。

伏羲介绍

“飞天”是阿里巴巴的云计算平台,其中的分布式调度系统被命名为“伏羲”(代码名称Fuxi),名字来自我国古代神话人物。伏羲主要负责管理集群的机器资源和调度并发的计算任务,目前支持离线数据处理(DAG Job)和在线服务(Service),为上层分布式应用如MaxCompute/ OSS / OTS提供稳定、高效、安全的资源管理和任务调度服务,为阿里巴巴集团打造数据分享第一平台的目标提供了强大的计算引擎。

伏羲系统设计上采用M / S架构(如图1所示),系统有一个被称为“伏羲Master”的集群控制中心,其余每台机器上会运行一个叫做“伏羲Agent”的守护进程,守护进程除了管理节点上运行的任务外,还负责收集该节点上的资源使用情况,并将之汇报给控制中心。控制中心与伏羲Agent之间使用心跳机制,以监测节点健康状态。当用户向伏羲Master提交一个任务时,伏羲Master会调度出一个可用节点在其上启动任务的主控进程AppMaster,主控进程随后会向伏羲Master提出资源请求,得到伏羲Master分配的资源后,AppMaster通知相应节点上的伏羲Agent开始运行任务Worker。伏羲是一个支持多任务并发的调度系统,控制中心伏羲Master负责在多个任务之间仲裁,支持优先级、资源Quota配额和抢占。

技术分享

使用伏羲,用户可以运行常见的MapReduce任务,还可以托管在线服务,满足不同应用场景的需求。多用户可以共享集群,伏羲支持配置分组的资源配额,限定每个用户组可以使用的计算资源。紧急任务如重要数据报表可以提高任务优先级来优先使用计算资源。

5K带来的挑战

在5K项目攻坚过程中,我们看到大型云计算平台从设计到实现每一步都可能存在性能“陷阱”,原因主要在三个方面:规模放大效应,当系统扩展到数千节点时,原本非瓶颈与规模成正比的环节,其影响会被放大;木桶效应,很多时候,系统中99 % 的地方都被优化过,完成剩下1 % 的优化看起来也只是“锦上添花”,然而那1 % 很可能就会成为影响系统性能的致命的瓶颈;长路径模块依赖,有些请求处理过程可能需要跨越多个模块(包括外部模块),而外部模块性能的不稳定性最终可能会影响到这个请求的处理性能和稳定性。5K项目是一场全方位战役,给伏羲系统带来规模、性能、稳定、运维等多方面的技术挑战,例如下面的性能“陷阱”:

  • 通信消息DDoS:在5000规模的集群中,不同进程之间的RPC请求数量会随规模猛增,网络中总请求数可达10000 QPS,极易造成系统中单点进程的消息拥塞,从而导致请求处理严重超时。另外消息处理还存在队头阻塞(HoL)问题。
  • 关键函数OPS:伏羲Master是资源调度的中心节点,内部关键调度函数的OPS必须达到极高的标准,否则就可能因为木桶效应影响到集群整体的调度性能。
  • 故障恢复对外部模块依赖:伏羲Master具有对用户透明的故障恢复功能(Failover),其恢复过程依赖写在Nuwa上的Checkpoint(注:Nuwa是飞天平台的协同系统,如名字服务)。因此,整体恢复速度会受到Nuwa访问速度的影响。

我们做了大量伏羲优化工作来规避上述的性能“陷阱”,涉及到架构设计、实现细节和模块依赖,透过现象看本质,从最底层性能分析入手一步步找到瓶颈。下面结合具体的实战例子来分享优化过程。

伏羲优化实战

通信性能优化

在5K项目初期阶段,我们测试大规模并发作业时发现,当作业数量超过1000时就容易出现运行时间变长的现象。分析监控曲线和日志,我们发现AppMaster发给伏羲Master的资源请求出现大量消息超时,AppMaster迟迟拿不到资源,资源请求处理的延时很高。

消息从到达伏羲Master进程到最终被处理返回的总时间主要包括在队列中等待时间和实际处理的时间,因此延时高无非是两个原因:消息处理本身的OPS下降;消息堆积在待处理队列中未被及时处理。顺着这一思路,在通过Profiling发现伏羲Master资源调度关键函数并没有占到整个消息处理延时的大部分后,罪魁祸首就只剩下消息堆积了。在绘出了伏羲Master中资源调度消息队列中消息堆积的曲线之后,果然发现当作业数量增加时,堆积的请求数量剧增(如图2所示),每一条请求的处理时间也较小规模时高出很多。

技术分享 

为什么在伏羲Master队列中会堆积如此多的消息?在伏羲系统中,守护进程伏羲Agent和AppMaster都需要向负责资源调度的伏羲Master查询资源状态,在通信策略上采用了定期Polling的方式,缺省是每秒查询一次。采用Polling通信方式主要基于其简单性,能比较鲁棒地应对网络故障,消息传递发送过程比较自然有规律。然而在5000规模集群中,这个策略必须进行调整优化,否则会造成伏羲Master被大量请求“DDoS攻击”而无法服务。

定位到消息堆积的问题后,我们立即对消息通信策略进行了流控,算法简单有效:发送端检查如果上次询问的请求结果已经返回,表明目前伏羲Master请求处理较为顺畅,则间隔一个较短的时间后进行下一次询问。反之,如果上次询问的请求超时,说明伏羲Master较忙(例如有任务释放大批资源待处理等),发送端则等待较长时间后再发送请求。通过这种自适应流控的通信策略调整,伏羲Master消息堆积问题得到了有效解决。

此外,我们还解决了伏羲Master消息的队头阻塞(HoL)问题。AppMaster需要与伏羲Master通信获得资源调度结果,同时也与伏羲Agent通信进行Worker的启停。由于伏羲Agent数量远大于伏羲Master,在极端情况下,如果AppMaster采用同一个线程池来处理这些消息,那么伏羲Master消息会被前面大量的伏羲Agent消息阻塞。我们将消息处理的全路径包括从发送到处理完毕等各个时间段进行了Profling,结果印证了队头阻塞现象。当一个任务的Worker较多时,AppMaster需要与之通信的伏羲Agent也会增多,观察到AppMaster拿到资源的时间明显变长。针对队头阻塞问题,我们通信组件中加入了独立线程功能达到QoS的效果,并应用在AppMaster处理伏羲Master消息的通信中。如图3所示,伏羲Master的消息单独使用一个线程池,其余消息则共用另一个线程池。

技术分享

通过上面的两项性能优化,伏羲系统内部的通信压力得到显著降低,提高了通信效率。AppMaster与伏羲Master之间的资源请求通信得到改善,任务提交后能很快分配到资源开始运行,提高了多并发任务场景下任务的完成速度。例如,经过这个优化,用户通过MaxCompute客户端对海量数据进行Ad hoc的SQL查询处理速度能得到显著提升。阿里云数加大数据计算服务MaxCompute产品地址:https://www.aliyun.com/product/odps

关键函数优化

在5K项目中我们还重点关注系统中的关键函数性能,那里也可能藏着“陷阱”。伏羲Master在调度资源时的一个关键操作是:比较一个节点的空闲资源能否满足该节点上排队等待的所有资源请求,从而决定该资源分配给哪个任务。这个函数的调用次数会与机器规模和请求数量成正比,因此其速度对伏羲Master的调度OPS有决定性影响。

伏羲在调度资源时支持多个维度,如内存、CPU、网络、磁盘等,所有的资源和请求都用一个多维的键值对表示,例如 {Mem: 10, CPU: 50,net: 40,disk: 60}。因此,判断一个空闲资源能否满足一个资源请求的问题可以简单地抽象成多维向量的比较问题,例如R: [r1, r2, r3, r4] > Q: [q1, q2, q3, q4],其中1、2、3、4等数字表示各个维度,当且仅当R各个维度均大于Q时才判断R > Q。比较次数决定了这个操作的时间复杂度。最好情况下只需比较1次即可得出结果,如判断 [1, 10, 10, 10]大于 [2, 1, 1, 1]失败;最差需要D次(D为维度数),如判断 [10, 10, 10, 1]大于 [1, 1, 1, 10]需比较4次。在资源调度高频发生时,必须对这里的比较进行优化。

我们通过Profiling分析了系统运行时资源空闲与请求情况,在资源充足时通常值最大的维度最难满足,因此在资源调度场景我们采用基于主键的优化算法:对每个资源请求的最大值所在维度定义为该向量的主键,当有空闲资源时首先比较主键维度是否满足请求,如果在主键上满足再比较其他维度。此外,对一个节点上排队等待所有请求的主键值再求一个最小值,空闲资源如果小于该最小值则无需再比较其他请求。通过主键算法,我们大大减少了资源调度时向量比较次数,伏羲Master一次调度时间优化到几个毫秒。注意到资源请求提交后不会改变,因此计算主键的系统开销可以忽略不计。

伏羲Master关键调度性能的优化增强了系统的规模扩展能力,用户利用飞天平台能管理更大规模的集群,容纳更多的计算任务,发挥出云计算平台的成本优势。

模块依赖性能优化

伏羲Master支持故障恢复,在重启后进行故障恢复时需要从Nuwa读取所有任务的描述文件(Checkpoint)以继续运行用户任务。考虑到之前Nuwa服务在服务器端对文件内容没有做持久化,伏羲Master在读取了Checkpoint后还会再写一次Nuwa,这个回写操作性能依赖于Nuwa模块。在5000节点的集群上,名字解析压力的显著增加导致Nuwa在Server的回写操作上也出现了性能下降问题,最终通过模块依赖传递到了伏羲Master,从而影响了故障恢复的性能。经测试观察,一次Checkpoint回写就消耗70秒,这大大降低了伏羲系统的可用性。

我们对伏羲Master故障恢复进行了优化。首先,从伏羲Master的角度,在故障恢复时刚刚读取的Checkpoint内容在Nuwa服务器端是不会发生改变的,因此读取Checkpoint后没有必要回写到服务器端,只需要通知本地的Nuwa Agent让其代理即可,Agent会负责服务器宕机重启时向服务器推送本地缓存的文件内容。于是与Nuwa团队的同学合作,在Nuwa API中新增加一个只写本地的接口,这样伏羲Master规避了在故障恢复时回写Checkpoint的性能风险。优化后,在5000节点集群和并发5000任务的测试规模下,一次故障恢复中处理Checkpoint操作仅需18秒(主要时间在一次读取)。可见在分布式系统中,对外部模块的依赖哪怕只是一个RPC请求也可能是“性能陷阱”,在设计和实现时尽量避免出现在关键路径上。

故障恢复是分布式系统保证可用性必须具备的功能,经过优化,伏羲Master的快速故障恢复增强了飞天计算平台的可用性和稳定性,屏蔽了硬件故障,使用户的使用过程不受影响。

工程经验

高质量代码没有捷径可走,也不能只靠制度流程,唯有认真二字:作者认真、Reviewer认真、测试认真。

  • 任何一个Item,无论是解决Bug还是新增Feature,都必须在动手写代码前讨论清楚方案,Code Review不能代替方案讨论。在讨论时作者需要回答两个问题:这个解决方法真的可行吗?副作用是什么?这些讨论需要记录在Wiki或者BugFree等工具上进行跟踪。
  • 小步快跑,尽早提交Code Review,很多问题在这个阶段就能发现,不必等到测试中发现,代价大。
  • 代码Reviewer对Item有一半的责任,因此Review时不是简单过一遍字面完事的。我采用的Checklist有:是否准确反映了之前讨论好的方案;是否存在死锁、“性能陷阱”;模块化封装是否足够;函数名变量名是否规范,日志格式是否规范;注释是否足够。一段代码Review迭代10次左右是很常见的。
  • 一定要有针对性的测试验证。
  • 代码提交时关联相应的Bug和Review ID,便于后续追溯。

总结

以上和大家分享了5K项目的一些实践经验,伏羲系统在5K项目中还做了很多有意义的系统优化和技术探索,参与其中收获颇丰。性能是功能的一部分,是系统生死线而非锦上花。5K项目只是阿里云计算平台技术发展的一个开始,未来会在更大规模和更丰富计算模型等方面进一步发展,为用户构筑可用可靠的云计算引擎,进一步降低成本,挖掘数据价值。

阅读原文直接点击

从浏览器渲染原理谈动画性能优化(代码片段)

...GraphicsLayer树,它们共同构成了"渲染森林"。保存了绘制DOM节点所需要的各种信息,与DOM树对应,RenderObject也构成了一颗树。但是RenderObject的树与DOM节点并不是一一对应关系。《Webkit技术内幕》指出,如果满足下列条件,则会创建... 查看详情

怎么优化hadoop任务调度算法

...工作。首先Hadoop集群式基于单服务器的,只有一个服务器节点负责调度整个集群的作业运行,主要的具体工作是切分大数据量的作业,指定哪些Worker节点做Map工作、哪些Worker节点做Reduce工作、与Worker节点通信并接受其心跳信号、... 查看详情

yarn资源调度框架

Yarn资源调度系统一、课前准备1.三个节点的hadoop集群二、课堂主题1.yarn架构、核心组件2.yarn应用提交过程3.yarn的调度策略4.yarn的优化三、课堂目标1.数据yarn资源的任务调度原理2.熟练对yarn集群进行维护3.了解如何使用YARN的可扩展... 查看详情

PM2 集群模式与节点集群性能

】PM2集群模式与节点集群性能【英文标题】:PM2ClusterModevs.NodeClusterPerformance【发布时间】:2018-01-1707:46:23【问题描述】:我了解PM2ClusterMode使我们能够轻松地在单台机器上跨CPU进行扩展。它是否创建了它正在扩展的节点应用程序... 查看详情

大规模k8s集群的优化思路(代码片段)

...大规模集群优化点调度器相关:1.在预选和优选时,多个节点之间并发的执行预选策略和优选策略(单个节点还是按顺序执行预选和优选策略的)2.算法执行过程中需要用到的如node、pod等信息使用Informer缓存起来3.当通过预选和优... 查看详情

《分布式技术原理与算法解析》学习笔记day10

...布式系统中的单体调度机制,它是指一个集群中只有一个节点运行调度进程,并介绍GoogleBorg的单体调度设计思路。调度框架:单体调度什么是调度?分布式系统架构的目的是将多个服务器资源管理起来,对外提供服务。调度是... 查看详情

k8s-集群调度(代码片段)

...ubernetes的调度器,主要的任务是把定义的pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题: 公平:如何保证每个节点都能被分配资源资源高效利用:集群所有资源最大化被使用效率:调度的性能要好,能够... 查看详情

es集群性能优化及维护

...置:ES7.0.0版本以上,默认只允许1000个分片。查询ES集群节点分片数:_cat/allocation?v8.ES集群API请求设置与配置文件设置优先级说明:集群属性设置方式:(1)API方式设置:a.临时设置(集群节点全部重启失效):9.ES集群状态异常,一直... 查看详情

浅谈性能优化之图片压缩加载和格式选择(代码片段)

在认识图片优化前,我们先了解下【二进制位数】与【色彩呈现】的关系。二进制位数与色彩在计算机中,一般用二进制数来表示像素。在不同的图片格式中,像素与二进制位数之间对应的关系是不同的。一个像素对应的二进制... 查看详情

一张图看明白云计算架构核心竞争力

...与节省节能减排等生命周期维护成本的节省弹性伸缩管理节点弹性伸缩能力数据中心资源的弹性伸缩能力承载用户数据信息及系统进行的存储集群弹性伸缩能力承载云租户业务的计算集群弹性伸缩能力高性能I/O吞吐性能、CPU调度... 查看详情

精品k8s的pod迁移与节点停机维护(代码片段)

目标:通过学习,了解pod迁移与节点停机维护的场景,以及需要注意的事项。内容:背景:某个节点由于某些原因经常故障,导致其上的pod与集群失联,造成整个集群问题流程:将问题节点k8s-node02设置为不可调度,然后重新调... 查看详情

elasticsearch性能优化干货

...数据量规划集群在业务初期,经常被问到的问题,要几个节点的集群,内存、CPU要多大,要不要SSD?最主要的考虑点是:你的目标存储数据量是多大?可以针对目标数据量反推节点多少。1.2要留出容量Buffer注意:Elasticsearch有三... 查看详情

k8s学习-集群调度(代码片段)

...ubernetes的调度器,主要的任务是把定义的pod分配到集群的节点上。听起来非常简单,但有很多要考虑的问题:公平:如何保证每个节点都能被分配资源资源高效利用:集群所有资源最大化被使用效率:调度的性能要好,能够尽快... 查看详情

从-view-绘制谈性能优化(转)

 在开发过程中,往往会听到“性能优化”这个概念,这个概念很大,比如网络性能优化、耗电量优化等等,对我们开发者而言,最容易做的,或者是影响最大的,应该是View的性能优化。一般小项目或许用不上View性能优化,... 查看详情

linux操作系统原理—numa架构中的多线程调度开销与性能优化

...使用大页内存前言NOTE:本文中所指“线程”均为可执行调度单元KernelThread。 查看详情

redis大集群扩容性能优化实践

...用Redis集群的业务随着业务量的上涨,往往需要进行节点扩容操作。之前有了解到运维同学对一些节点数比较大的Redis集群进行扩容操作后,业务侧反映集群性能下降,具体表现在访问时延增长明显。某些业务对Redis集... 查看详情

kubernetes:如何实现跨集群节点均匀调度分布pod(pod拓扑分布约束)(代码片段)

写在前面分享一些k8s跨集群节点均匀调度分布Pod的笔记博文内容涉及:pod调度&&拓扑分布约束简单介绍跨节点均匀分布podDemo&&相关配置字段说明多个拓扑分布约束Demo有冲突拓扑分布约束Demo理解不足小伙伴帮忙指正<... 查看详情

linux操作系统原理—进程管理—numa架构中的多线程调度开销与性能优化

目录文章目录目录前言NUMA体系结构基本对象概念查看Host的NUMATopologyBash脚本DPDK脚步NUMA架构中的多线程性能开销1、跨Node的Memory访问开销2、跨Core的多线程Cache同步开销3、多线程上下文切换开销4、CPU运行模式切换开销5、中断处理... 查看详情