大数跨境
0
0

石龙飞:小米Hadoop YARN弹性调度的探索与落地

石龙飞:小米Hadoop YARN弹性调度的探索与落地 Apache Iceberg
2022-05-23
0
导读:分享嘉宾:石龙飞 小米集团编辑整理:刘兆磊 枣庄学院出品平台:DataFunTalk导读:大家好,我是来自小


分享嘉宾:石龙飞 小米集团
编辑整理:刘兆磊 枣庄学院
出品平台:DataFunTalk

导读:大家好,我是来自小米数据中台的石龙飞,今天分享的题目是《小米Hadoop YARN弹性调度的探索和落地》,主要分五部分内容来讲,重点分享小米弹性调度的架构设计,以及我们如何应对落地过程中种种挑战,希望能对降本增效、资源调度、弹性计算感兴趣的同学有所帮助。
  • 背景

  • 弹性调度

  • 难点挑战

  • 弹性成果

  • 未来规划

01

背景

1. 背景

上图是一个时间周期为六天的离线集群资源使用的监控,可以比较明显地看到,在0到12点有一个高峰,在12点到晚上这段时间有一个下降甚至有一个低谷。那么第一个背景就是我们的离线集群全天平均资源利用率不高,另一个背景就是随着小米业务的扩张,底层计算的需求规模越来越大,一些小的优化能带来的绝对值是非常大的,所以进行小米离线计算的降本增效势在必行。
2. 目标

针对降成本,我们制定了三个目标:
  • 第一个目标是把计算低谷时的闲置资源优化掉

  • 第二个目标是希望能够使用更加廉价的计算资源

  • 前两个目标是我们做弹性调度的目标,在完成前两个目标的基础上,我们一定还要保证作业的稳定性不受影响

02

弹性调度

1. Hadoop YARN 架构

因为弹性调度是基于Hadoop YARN来做的,所以我们先简单了解一下YARN的架构,YARN是一个典型的master和worker的结构。master是ResourceManager,它负责集群的资源管理和作业调度,NodeManager是worker节点,它负责管理单个节点上的计算任务,可以把 NodeManager 所在节点看作是计算实例,或者计算资源。
2. 弹性资源池

再来介绍一下弹性资源池的概念。资源池其实是一个比较抽象的叫法,它实际上可能对应的是一批计算实例,或者是一批物理机器,甚至K8s的pod。在调研之后,我们最终选择了三种机器来作为我们的资源池:
  • 公有云按需实例(OD)

  • 公有云抢占实例(Spot)

  • 内部在线业务机器

主要从成本、稳定性、资源池大小以及使用的技术难度这四个维度对它们做了一些分析,结论如上图中所示。
公有云的按需实例(On Demand, OD),它的特点是非常稳定,并且数量很大,但成本优势不显著,比集群正常机器成本略低或者持平,使用不合理的话成本可能会更高。公有云的抢占实例(Spot),特点是便宜,我们调研过阿里云和AWS,完全一样的机器抢占实例大概是OD机器价格的20~30%,但是抢占实例需要去克服稳定性的问题;因为Spot节点的机制是,公有云将自己空闲的资源拿出来给用户使用,当公有云遇到资源紧张的情况时,随时会把这部分资源给回收回去,造成Spot的不稳定。第三个就是内部在线业务的机器,它的特点是零成本,用或者不用,资源就在那里,不多不少。还有一个特点是按时释放,一般在线业务高峰来的时候,需要把这些资源主动归还甚至被抢占,不然可能会影响在线业务。同时在线离线混布方案较为复杂,有较多技术难点。
基于以上这三种资源,理想的资源使用策略是:将内部在线业务所有闲置的机器资源都能够用起来,剩余的缺口使用公有云的抢占实例来补足,最后还需要用按需实例来作为兜底,兜底的原因是抢占实例不一定任何时候都可以申请到。
3. 弹性调度描述
有了YARN的基本介绍和资源池的概念之后,就可以简单描述一下我们对弹性调度的定义:
弹性调度就是基于一个或多个资源池,根据一定的弹性策略,将YARN集群进行动态扩缩容。
有三个重点,第一是资源池,第二是弹性策略,第三是如何动态扩缩容。接下来就围绕这些点展开讲解。
4. 整体架构设计
这是弹性调度的整体架构。右上角是一个普通的YARN集群的架构,有中心节点ResourceManager,还有一些Node节点,左边是我们使用弹性调度之后新增的内容。
首先可以看到AutoScaling这个模块,它通过一些既定的规则或者感知集群的状态,去对节点进行申请或释放。比如感知到集群资源比较紧张时,会告诉资源池的控制器拉起一些节点,然后这些节点会注册到ResourceManager上,这时集群就得到扩展。相反,当集群资源比较空闲,压力较小时,AutoScaling感知后告诉资源池,将这些节点慢慢的释放掉,这样就实现了缩容,集群又回到了原来的样子。
图的下方展示的是上述整个过程对应的集群真实的资源使用情况,红线是我们集群一天中的实际资源负载,黄线圈出来的部分我们称它为常驻资源或者default资源,就是不管资源如何波动,这部分资源是一定要有的,它是由右边YARN集群里标黄的这部分节点来提供的。用蓝色虚线圈出来的部分,我们叫它弹性资源,是由弹性资源池中的节点来提供的。绿色的这部分是我们省出来的一些资源,相对应是我们可以节省下来的成本。同时弹性资源这部分,我们会用到更加廉价的机器,所以这部分资源相比原来的成本会更加便宜。
整个过程有两个关键动作:第一个是在高峰扩展,使用资源池中更加廉价的计算资源,第二个是在低谷释放,优化掉闲置的资源。这里引入了个关键概念:弹性节点/资源,它的特点就是周期性的拉起和释放,同时它运行中还可能伴随着被下线的可能,这是它暗含的一些稳定性问题。
5. AutoScaling设计
接下来看一下核心模块AutoScaling的工作原理。
  • ClusterMonitor组件,这个组件就是去监控ResourceManager的状态信息,提供给后边其他组件使用。

  • ScalingStrategy是弹性策略,它的职责是生成资源弹性伸缩的结果,这个结果包含伸缩的动作,以及伸缩容的资源量。

  • SpotManager负责去接收资源伸缩的结果,然后通过Scaler去执行真实的伸缩动作,它其中还维护着一些Spot的结构。Spot可以理解成计算实例,它物理上就对应着一台机器或者一个K8s的Pod,它里面会记录一些计算实例的基本信息。

  • Scaler是伸缩器,它需要有多种实现去适配不同的资源池,比如说可能需要适配AWS、阿里云、金山云,甚至还有K8s。一个AutoScaling可以有多个Scaler,去调度多个资源池。

6. 弹性策略

策略是弹性非常关键的一个点,我们目前的策略有两个。
第一个是根据静态的历史负载情况来做决策。我们通过之前集群的负载,已经知道它的负载曲线是怎样变化的,我们直接将这个作为弹性策略的输入,这样就可以通过历史情况判断出今天某一个时间点需要多少资源,然后根据这个判断去做弹性。这个策略非常简单,好处是非常稳定,但是它无法适应突发的资源需求。比如前一个星期或者前一个月的下午都没有任何资源突增,但是到年底大家突然开始回溯历史数据,那下午就会有一个临时突增,像这种情况第一个策略就没有办法满足,需要额外的手段去干预。
第二个策略是根据集群的动态资源需求来做一些决策。根据集群pending的资源、集群逻辑负载、节点物理资源使用情况,评估出集群接下来要有什么样的动作,要扩容还是缩容,并且这个扩缩容还需要在一定范围内,否则资源波动可能会比较大。这个策略的特点是非常灵活,可以适应比较复杂的集群对资源需求的变化,但由于考量的因素以及决策结果都非常复杂,其稳定性还有待考验。
目前我们线上集群使用的还是第一个策略,效果较为理想,第二个策略我们现在正在测试和验证中。
03

难点挑战

前面的介绍偏向于理论,距离真正上线使用还有很多困难。接下来看一下我们在弹性调度落地过程中遇到的一些挑战,其中主要有两个挑战:保证作业稳定性和如何对用户透明。
1. 作业稳定性
①作业稳定性-Label

首先需要引入YARN的Label概念,左边这个图是不引入Label下的集群状态,所有的节点都是默认节点,队列配置的资源都是默认的资源,App使用的也是默认资源。当引入一个Label X之后,可以给一些节点打上X标签,同时队列也可以去配置X资源,作业也可以使用到X资源。

我们将Label特性与弹性调度相结合来提升作业的稳定性。可以看左边这个图,我们在引入弹性资源之后,集群的整体资源分成了两部分,一部分是default资源,另一部分是弹性资源。
在不打Label的情况下,所有资源是一模一样的,对作业来说没有任何区别。但是,集群中有Flink作业,跑一周甚至一年都是有可能的,因为弹性资源会周期性地释放掉,所有对Flink作业影响特别大,天生不适合Flink(当然Flink目前也在在做动态调度,资源有波动后,也可以使用弹性资源),因此Flink不建议/禁止使用弹性资源。另外就是作业的AM组件,它的稳定性非常重要,所以也不建议使用弹性资源。
想要把这两部分资源隔离,就需要使用到Label,分别给默认节点和弹性节点打上各自的Label,这样作业提交的时候指定使用默认资源,而不是弹性资源,就可以避免Flink作业去用弹性资源,做到资源隔离。
之后我们又发现了另外两个问题,第一个问题是单个作业存在多种资源类型的需求,比如Spark、MR(MapReduce),既可以用default资源,也可以用弹性资源,但是原生的YARN只可以配置一个标签,到底配哪个标签就是一个问题。第二个问题,可以看一下右边这个图,假设橙色曲线是弹性资源一整天的变化情况,在零到十二点高峰时,给App配一个弹性的Label,当然可以正常运行,但是当下午弹性资源慢慢释放掉并归零之后,如果配置的只是弹性资源,作业就没法跑了,这是不能接受的。
由此,我们开发了Label表达式的功能,表达式类似于 ||spot||od,它表示这份资源申请可以接受default、spot、od中任意一种。因为default的标签实际上就是一个空串,所以这个地方解析出来,其实是有一个空串存在,所以表示三种资源都可以用。
这样的话,我们就解决了弹性资源和default资源的隔离问题。
②作业稳定性-节点平滑下线

第二个解决作业稳定性的办法是节点平滑下线。Decommission节点时会标记节点将要下线,但是先不下线,等节点上所有的作业以及task跑完之后才真正下线。我们将YARN的Decommission机制与弹性调度相结合,得到了作业稳定性的大幅提升。
弹性调度工作的流程如上图所示,AutoScaling会将要下线的节点写到exclude文件里,然后ResourceManager去加载,标记节点为Decommissioning状态。AutoScaling会定期从ResourceManager查询节点的状态,如果发现节点从Decommissioning变成了Decommissioned状态,AutoScaling就去真正释放这个弹性节点,这样可以保证这个节点上的很多计算任务不会失败。
③作业稳定性-Spark

作业稳定性的第三个优化是专门针对Spark作业的,因为我们集群目前batch离线作业80%的资源都是Spark使用,所以只要解决好Spark问题其他问题就都不大。
上图可以看到节点下线它会带来哪些问题。第一个是计算节点上的一些临时数据会丢失,这些数据一般都是Shuffle数据,数据丢失后,如果下游的task需要这些数据,就需要再拉起这个数据前面依赖的计算任务,再把这个数据重新算出来一遍,这样会浪费很多计算资源。第二个问题是,正在跑的task会失败,如果task失败太多,会导致作业整体失败。
我们的解决办法主要有两点。第一个是Spark Remote Shuffle Service服务,它将Spark的中间Shuffle数据写到一个服务中,而不是本地磁盘,这样即使节点下线数据也不会丢失。第二个是Spark作业去感知节点的状态,这个状态指的是NodeManager的状态,需要将节点异常情况下失败的task不计入真正失败的task,这样会避免作业因为有太多失败的task而导致失败。
以上就是对作业稳定性的一些优化措施。
2. 用户无感知
①用户无感知-队列

我们刚开始上线弹性时,有推动用户手动去加一些配置,很快我们发现这样做对用户太不友好了,所以我们马上调整策略,将对用户透明提到很高的优先级。
上面左边这个图,这是用户队列的资源使用监控曲线,周期是三天,可以看到比较明显的周期性,在0-12点又一个高峰,随后是低谷,队列配置了100个单位的资源。
队列接入弹性后,我们将这个队列资源拆分成了两部分,第一部分是默认资源,调整到了60,以保证低谷时队列也有资源可以使用;第二部分是新增弹性资源40份,这样队列在高峰的时候总共有100份资源可以使用。上述过程都是通过自动化来计算调整的,调整完之后,用户的队列就可以正常使用默认资源和弹性资源,队列的整个接入过程对用户都是无感知的。
②用户无感知-作业

作业接入也需要做到对用户无感知,前面提到Flink、AM等不能用弹性资源,batch作业也并不都适合接入,所以我们要进行定向接入。
我们对分析了作业画像,主要通过两个维度来筛选,第一个是时间维度,找到作业的运行周期与节点下线的时间不重合的。第二个维度是作业的优先级,低优作业更适合接入。通过这两个维度能确定作业是不是可以接入弹性,能够接入的话,我们的灰度系统会自动为作业添加必要的配置,比如label表达式。整个过程也都是自动化的,不要用户感知。
比如第一个App,虽然运行时间长,但是它和节点下线时间不重合,所以可以弹,第二个有重合,就不能弹,第三个运行时间非常短,即使它的生命周期全处在节点下线时间也可以让它使用接入弹性。另外就是像红圈圈出来的高优作业,即使运行周期符合要求,也不可以接入弹性;相反,一个低优作业,即使它运行时间很长,也可以让他尝试接入弹性。
3. 其他问题

我们还遇到了很多其他问题,像YARN原生对Label的支持非常不足,尤其是监控方面,我们对Label做了一些单独的开发,提高了它的可观测性,还做了很多关于Label的bug fix。
另外,弹性的节点需要运行NM,我们使用了内部的灰度系统来对弹性节点上的NM的版本进行控制、升级等操作。
第三是我们基于内部的YARN元仓的项目,通过离线分析队列和作业数据,实现队列和作业自动接入弹性的资源。
最后一个问题,也是非常头疼的一个问题,就是原有集群是在自建IDC,准备向公有云弹的话,会遇到带宽问题,这个带宽还是相当大的。如果不跨IDC到云,或者不跨公有云的region,那么带宽问题就基本不存在,这个问题我们现在也没有得到一个很好的解决办法,我们目前线上跑的是在公有云的同一个region下,所以暂时没有这个问题,后续会研究解决跨 region 的带宽问题。
04

弹性成果

接下来简单展示一下弹性的成果。左侧图的红色线依然是我们集群的资源使用的曲线,蓝色的线是不做弹性时集群可用的资源,它是一条静态的直线。在我们做完弹性之后,集群可用的资源就是这条绿色的线,绿线和蓝线之间的部分,是我们省出来的资源,也就是优化掉的空闲的资源,和我们的目标是相符的。
右边的图列举了使用公有云的按需实例和抢占实例,分别能带来的成本优化的效果,如果在不使用弹性的情况下,假设集群成本是100,那么在使用了按需实例之后,并且按需实例是整个集群资源25%的情况下,可以节省集群12%的成本,如果全部使用抢占实例,可以节省20%。
我们现在的状态是以按需实例为主、抢占实例为辅。现在正在推动由按需到抢占的切换,当全部切到抢占实例之后,我们就可以达到20%成本优化的效果。
05

未来规划

最后,简单介绍一下我们未来的规划。
第一部分是AutoScaling这个模块本身的优化,我们准备与RM做一些整合,这样一些指标的感知、还有节点上下线的操作,都会更加简单方便。优化弹性策略,使弹性更加精准可控。在节点下线的时候,也会做一些优化选择策略。
第二个内容是,把在线资源用起来,主要就是尝试在线离线的错峰或在离线混布。另外,希望把在线资源做的更加抽象,和公有云的资源效果类似,这样在实现层面上会更加统一。
以上就是小米Hadoop YARN弹性调度落地的全部内容,感谢大家阅读观看。
除了上述弹性调度,我们还在分布式调度其他方向进行这深入研究探索,欢迎志同道合的朋友加入我们,共建小米统一调度平台,也欢迎大家联系我们,一起交流探索。
历投递:shilongfei@xiaomi.com
邮件标题:姓名-小米大数据-分布式调度应聘

今天的分享就到这里,谢谢大家。


在文末分享、点赞、在看,给个3连击呗~


分享嘉宾:

免费资料下载:

《大数据典藏版合集》

《互联网核心应用算法宝藏书》

(向右滑动查看全部目录)


 如何下载资料合集?

识别二维码,添加小助手微信,回复:

『大数据典藏版合集』或

『互联网核心应用算法宝藏书』

即可下载对应资料

关于我们:

DataFun:专注于大数据、人工智能技术应用的分享与交流。发起于2017年,在北京上海深圳杭州等城市举办超过100+线下和100+线上沙龙、论坛及峰会,已邀超过2000位专家和学者参与分享。其公众号 DataFunTalk 累计生产原创文章700+,百万+阅读,14万+精准粉丝。

🧐分享、点赞、在看,给个3连击呗!👇

【声明】内容源于网络
0
0
Apache Iceberg
为你提供 Iceberg 社区资讯、功能特性以及技术分享。
内容 76
粉丝 0
Apache Iceberg 为你提供 Iceberg 社区资讯、功能特性以及技术分享。
总阅读0
粉丝0
内容76