欢迎访问火狐体育注册,咨询电话:400-658-0379
首页 > 新闻中心 > 技术相关

vivo 在离线混部探索与实践

来源:火狐体育注册    发布时间:2024-02-29 17:33:09

  伴随 vivo 互联网业务的快速地发展,数据中心的规模逐步扩大,成本问题日渐突出。在离线混部技术能在保证服务质量的同时,极大的提升数据中心资源利用率,减少相关成本。混部技术涉及任务调度、资源隔离、运维观测等一系列技术难题,本文将介绍 vivo 在混部技术方面的实践和探索,为读者提供借鉴和参考。

  数据中心运行的服务可大致分为在线服务和离线任务两大类,它们具有不一样的资源使用特征。

  通过混部技术,我们大家可以将在线和离线部署到同一台物理机上,形成资源互补,提升物理机的资源利用率,减少相关成本。混部技术最早由谷歌在2015年提出,经过多年的发展,混部技术已趋于成熟,目前业内利用混部技术能将数据中心的CPU利用率提升至40%左右 。

  强大的调度能力解决了,我们如何将离线任务高效、合理的调度到在线服务所在的物理机上。而强大的隔离能力保障了在线服务的质量不受离线任务干扰。完善的监控和运维能力则可以让我们洞悉整个混部平台的运作情况,及时有效地发现潜在风险,帮助运维人员更高效的完成系统和业务的运维工作,保障集群的高稳定性。

  同时为了尽最大可能避免整机负载太高影响系统的稳定性,我们设置一个安全水位线 混部QoS等级

  通过混部产品能力的建设,我们很好的实现了容器混部能力,但是在实践中我们仍旧是遇到一些新的挑战:相对于普通K8s集群,混部集群中运行着更多的容器,而且离线任务由于生命周期短,容器创建销毁更为频繁,这对K8s apiServer 产生了很大的压力。

  所以我们拆分了apiServer ,离线任务使用独立的apiServer ,保障了集群apiServer 负载长期处在一个安全水平。

  同样混部之后由于采集了更多的监控指标,导致Prometheus内存消耗过多,不足以满足平台指标 采集需求。针对这样的一个问题,我们优化了监控架构,将在线和离线监控组件分开部署,离线改用性能更好的vmagent,通过这一个优化,监控组件内存消耗减少到原来的十分之一。

  混部初期虽然集群CPU利用率有所提升,但是还是未达到我们的预期,根本原因有:

  二、Java 类应用堆会固定占用大量内存,导致可提供给离线使用内存资源不足。

  针对这样一些问题,我们开发了定时调整安全水位线功能,在业务低峰期上调安全水位线,释放更多的资源给离线使用。通过一系列的优化手段,我们将其中一个混部集群的CPU利用率由13%提升到了25%左右,几乎翻倍,混部效果得到了有效的验证。

  从业务适用性来说,YARN on K8s 是通用的,可以兼容Hive、Spark、Flink这些引擎,它不需要频繁创建Nodemanager pod,对K8s的压力比较小。这些都是它的优点,但另一方面,Nodemanager ESS服务是对磁盘有容量和读写性能要求的,混部机器磁盘一般难以满足。所以我们要支持不同引擎的remote shuffle service。

  如果计算引擎有不同的版本,那么RSS也要支持不同版本,比如Spark2,Spark3。如果你有不同的引擎,不同的版本,很可能一种RSS还满足不了需求。另外Nodemanager应该要依据K8s混部节点的剩余资源,动态调整可用的vcore和内存,所以还需要一个额外的组件来做这个事情,这需要较高的改造成本。在资源利用上,NM的资源粒度相对大,自身也会占用一些资源,存在一定的浪费。在资源紧张的情况下,Nodemanager作为整体被驱逐,会影响多个任务。这些是YARN on K8s的劣势。

  首先这个特性在Spark 3.1以上版本才正式可用。Spark on K8s由于会频繁的创建、查询、销毁大量的executor pod,对K8s的调度能力及master节点会造成比较大的压力。另一方面,它的优点是只需要能支持spark3.X的RSS,这有较多的开源产品可选择。而且改造成本比较低,不需要额外的组件。资源粒度小,更加有助于充分的利用集群资源。在资源紧张时,会逐个pod进行驱逐,任务的稳定性会更高。

  要达到阶段一的目标,让任务跑通、跑顺。我们主要克服了哪些核心问题和挑战?

  第一个是日志查看,因为Spark Operator方式并没提供已结束作业的日志查看方式,包括driver和executor日志。在Driver侧,我们通过定期请求容器开放API,能准实时地获取Driver Pod状态与日志。在Executor侧,我们参考了on yarn的方式,Executor Pod结束后,日志上传HDFS,与YARN日志聚合类似。

  大规模双跑,目的是确保Spark任务迁移到K8s集群后是兼容的,任务成功率有保障;任务执行时长是稳定的,不会明显变慢;数据是准确的,跟on YARN保持一致性。为此,我们应该对任务进行on YARN和on K8s两种模式下的双跑测试,我们分批次总共进行了7轮双跑,覆盖了2万+的线上正式任务。最终也取得了我们想要的结果:我们双跑最终达成的任务成功率超过了99.5%,绝大部分的任务在两种模式下的时长波动在25%以内,数据一致性是100%。

  混部集群的压力联调,目的是确保混部集群的承载容量能够支撑大规模的离线任务调度,通过模拟未来1年的任务量来给混部集群做压力测试,充分发现和检测K8s集群可能存在的性能问题。最终,通过我们多轮压测和问题解决,我们在单个K8s集群能够支撑150+同时运行的Spark任务,1万+同时在运行的Pod数量。

  首先是我们应该为Spark选择一个外部的shuffle服务,经过技术选型和比较,我们最终选择开源的celeborn作为我们的remote shuffle service组件。我们通过对机型和参数的测试调优,使celeborn的性能达到我们的预期需求。在大规模的应用场景中,我们还发现了会存在大任务会阻塞小任务,导致shufle read变慢的问题,我们对这样的一种情况做了参数和代码上的优化,当前社区也针对shuffle read的问题有一些待优化的改进。另外celeborn进行了容器化部署,在提升自动化运维能力的同时,也可以为混部集群提供额外的计算资源。

  我们K8s apiserver的压力随着任务量增长压力也会逐渐增大,这会影响整个集群的稳定性。我们主要是通过优化Spark driver list pod接口、使用hostnetwork方式两个优化手段,大大降低了apiserver的压力。

  最后要说的是数据一致性,关键点是要做到行级记录的MD5校验,发现有不一致的Case,我们做到100%的分析覆盖。排除了由于时间戳随机函数等一些预期内的不一致,我们得知并修复两种case会偶发导致不一致的问题:

  在弹性方面,我们应该做到实时根据混部集群资源闲忙,智能提交至混部集群或者Hadoop集群。在前期我们K8s集群的资源相对Hadoop是小头,通过合理的水位线控制,防止大量任务同时调度到K8s导致饿死。

  在满足业务需求方面,我们支持优先调度本业务的离线任务, 优先满足业务部门的离线任务资源需求;支持只在指定时间段里调度离线任务,支持在出现不正常的情况下一键终止调度K8s。这些是为了确认和保证在线服务的高可用性,免除在线 混部效果

  我们目前可供调度的任务接近2万个,这些任务每天调度的次数已超越了4万次。在凌晨的高峰期,我们通过混部,能为离线TB内存的计算资源。这个收益是相当可观的,我们也希望在未来的2到3年,将可调度的任务规模提升到6万个,弹性资源能够为离线%的份额。

上一篇:【技能干货】VoLTE接通率剖析
返回列表
下一篇:vivo 在离线混部探索与实践