Py学习  »  机器学习算法

4 个月节省千万成本的机器学习混部实践

InfoQ • 7 月前 • 187 次点击  

作者 | 王元良
编辑|邓艳琴  

当前,各大公司都存在着线下集群利用率不高的问题,且在尝试进行多业务类型的混合部署后,还可能会遇到各种稳定性和业务质量方面的挑战。因此,贝联珠贯在大数据领域针对万台规模的集群展开了研究,并成功落地了一种基于增强型 RunC 的新方案,在第一阶段的 4 个月里,成功地帮助客户提升了资源利用率,年度降本超过千万人民币,同时业务使用体验并未受到影响。在今年 9 月份的 QCon 全球软件开发大会(北京站),贝联珠贯 (www.lccomputing.com) 合伙人王元良老师以《增强型 RunC 的最佳实践:克服离线高压力混部场景的关键挑战》为题,分享了实际落地经验。本文由贝联珠贯公众号(ID:Lccomputing)整理节选自此次演讲。

完整幻灯片下载地址:
https://qcon.infoq.cn/202309/beijing/presentation/5440
背   景

在当前经济形势下,各大公司都在努力降低成本并提高效率。我们观察到,目前不少公司存在着线下集群利用率不高的问题,在线集群小于 10%,离线集群 40% ~ 60% 左右,提升利用率的空间还很大。

我们这位客户的大数据集群包含数百万任务和万台物理机,资源利用率在 50%,期望通过将未使用的计算能力出让给机器学习业务,提升资源利用率并降低成本。在尝试进行多业务类型的混合部署后,各种资源问题导致服务质量无法保证,如 任务 hung 死、OOM、系统负载过高、IO wait 超高、机器宕机等。因此,我们在大数据领域针对万台规模的集群高吞吐、高压力展开了研究。

场   景

首先,来看一下客户环境的资源情况。如上图所示,离线集群在时间上存在典型的潮汐现象。资源视角上,大数据任务和机器学习任务都是计算和存储密集型,并且有大量的网络数据流量,这必然给机器带来很大的压力。

所以在混部出让算力时,优先需要考虑的是高压力场景下,业务如何稳定运行的问题。

关键挑战

项目初期稳定性问题挑战很大,一度导致项目停滞不前,具体表现为:

每天有超过 1% 的机器宕机

  • 一周内,近三分之一的任务出现过 hung 死

  • 三周内,hung 状态的任务比例接近 100%

  • 出现了一些常规无法解释的现象

    • 例:内存利用率为 70% 的机器出现了挂机现象,而内存利用率 90% 的机器却没有挂

  • IO wait 时间超高,系统负载过高

我们意识到,仅针对问题点进行解决是不可行的,这会导致陷入问题泥潭无法抽身。必须换一种思路,达到既能解决当前问题又能预防未知问题。

增强 RunC 思路与实施

在深入探讨解决问题的方法之前,我们先来探讨下思路的出发点。

在分布式系统中,Linux 扮演了分布式操作系统驱动程序的角色,而操作系统的核心能力由单机提升到了分布式层面。

众所周知 Linux kernel 资源面的参数不下百种,经常收到 K8s 工程师抱怨 Linux kernel 参数复杂、组合多,不知道如何使用。Linux 是个适配 N 多场景的操作系统,这就导致它只能提供基础能力,而非专门针对分布式来设计。

想要解决好资源问题,看起来从架构角度改变“各玩各的”状态,促进紧密协作势在必行。

主动预防优于被动应对

一个可执行程序可以被划分为几个逻辑部分:业务逻辑、CPU 资源使用、内存资源使用、IO 资源使用以及网络资源使用。从汇编的角度看,这些部分是利用 CPU 进行计算、访问和申请释放内存、访问 IO 以及网络等操作,这些资源部分可以被视为业务逻辑的子模块。资源面的问题往往先于业务面出现,并逐步恶化,最终影响业务。

我们期望通过监控资源面的波动来预防业务面的问题,来替代原来事后弥补的思路。

统一语言,让 K8s、YARN 读得懂资源信息

想要做到事前预防,首先要解决的就是建立单机 (Linux kernel) 与分布式 (K8s) 之间的高效沟通。必须具备简单高效、符合关键需求、双方都能读得懂等特点。

在线业务关注响应时间 (RT)。业务同学要求在 RT 波动时配合排查资源面问题。但 RT 变化快,资源面参数多,难以找到问题根源。离线业务在意吞吐量、任务完成度和机器稳定性,还有单点故障导致的分布式任务失败。此次一并思考解决办法。

选择 RT、压力和边界作为指标。既满足业务读得懂,简洁高效,又是双方都在意的关键点,看起来是说得通的。这样就在资源和业务逻辑之间建起了通道,并画了一条区分界定的分隔线。实现思路是在内核中对各个链路进行打点。难点在于性能和功能之间的平衡。

实施效果

图左是在客户场景中实施后的效果,右侧是我司内部业务场景的一个例子。

可以看出,右侧 Memory 部分的波动与上方业务的波动时间是相拟合的,符合预期效果。然而,波形并不完全一致,是因为业务逻辑包含了多个部分。这些时刻,业务逻辑并没有在访问 Memory,而是在访问其他资源或利用 CPU 进行业务逻辑运算。也解释了为什么 Memory 波动大于业务波动。

各自安好 vs 紧密协作

介绍了统一沟通语言后,我们来看下客户场景的边界问题是如何通过分布式层与 Linux kernel 之间紧密协作来解决的。

先看下前面提到的情况:当内存利用率达到 70% 时,部分机器会挂掉,而另一部分集群,即使内存利用率达到 90%,也在正常运行。这超出了单机上 free 参数的常规理解。

分析发现问题出在内存碎片、IO 拥塞、Page Cache 中 dirty 页过多、内存压力大导致分配基本都走了 slow path 等因素,一句话总结为健康程度低带来的剩余内存不可用。

在这我们不想仅针对单点问题来逐个解决,既然存在各种各样的健康问题,做归一处理更有效。我们将多年反复定位的重复动作固化到代码里,生成了一个健康度指标,给出了一套分布式与单机的联动方案。具体如下 (如图):

  • Normal 健康态:机器处于正常健康状态,业务可以安心地使用内存资源。

  • 突破 Normal 到达 Minor 态:内存使用量达到一定程度并且内存的健康度变差,通知 NodeManager 或者 K8s 停止向该机器调度新的任务。

  • 突破 Minor 态到达 Severe 态:情况继续恶化,在当前压力下进行减压,如:驱逐任务、杀死低优先级任务等。

  • 突破 Severe 到达 Critical 态:优先保障机器不挂、保护型任务能够正常运行,除保护型任务外皆可杀。

  • 当压力得到缓解后,只有当恢复到前一级门限时,才会解除上一级的警戒状态。

同时加上内存申请的突增速度的因素。每级门限之间的缓冲区起到了战壕的作用,这样可以逐级、小步切分地解决问题。使得资源问题从有征兆到很严重的过程均在感知与监控下,并和分布式进行及时的联动。

接入客户系统

  1. 一级告警,LCC-Agent 通知 NM,NM 会调整心跳时间,心跳时间从 3s 变为 5min
  2. 二级告警,LCC-Agent 通知 NM
    1. NM 会调整心跳时间
    2. NM 会根据任务的优先级,优先 KILL 低优先级任务
  3. 三级告警,LCC-Agent 直接 kill 非白名单进程
    机器夯死问题得到解决,混部解决掉最关键的资源卡点问题,稳定性问题收敛,未再出现此类问题
实施效果

在产品上线前,每天都会出现几十次的整机 OOM。然而,上线后,这种情况逐渐得到了改善。初期上线时,仍然会有少量的 OOM 出现,这主要是因为进行业务联调,当时只开启了第三级门限。但随着一级和二级门限的联动开启,这个问题已经得到了有效的解决,至今已稳定运行四个月。

集群维度感知,先于业务发现问题

前期为了了解客户混部集群中的各种资源问题状态,我们采用手动脚本单台机器日志并聚类的方式来拿到结果;这种方式耗时长 (两周一次)、只能分析问题大类、没法观察问题走势和分布等。

混部后单机压力与复杂度指数级上升,需要高频全视角的分析问题,这种方式不再适用。需要一套能分钟级展示、多视角、自动聚类分析的手段,包括时间对比、子系统分布、问题大类、问题子类、业务角度等。这样才能摆脱事后单点分析的局限,全面掌握客户集群的资源状况,并及时观察其变化、影响和走势。

我们对 Linux 内核中的代码级问题进行了分类和总结,并生成了 ElasticSearch 的字典。这样可以看到各个子系统的情况,甚至代码级别的问题。比如:文件系统(FS)有问题的机器是哪些,以及它们运行了哪些业务。还可以通过时间变化判断问题走势。比如:上图显示了 xfs_aops.c 文件 1045 行有问题。

统一调度

为了完成两种业务对集群的融合使用,除了解决资源面干扰外,还需要实现资源统一调度,理论上有四种思路,各有其优缺点:

  1. 容器化 ML 任务,使用 YARN 进行调度。理论上可行,但实现 ROI 较低。

  2. 在 Kubernetes 中实现 YARN 功能,以实现统一调度。尽管这个方案技术上很合理,但工作量较大,无法满足业务四个月上线的目标。

  3. 将 YARN 部署为 Kubernetes 中的服务,并由 Kubernetes 进行管理。这种轻量级且易于实现的方式可能是一个解决方案。

  4. 在物理机上运行 YARN,同时在 Kubernetes 上运行 ML 任务。根据预设规则来协调资源使用 (Autoscaler),由单机 Agent 解决资源使用问题,以保证资源的流畅使用。

综合评估下来,第四种方式最符合时间进度和工程简化的要求。具体实现中,还完成了以下工作:扩缩策略感知、审计日志上报、动态资源感知、NM 资源设置和资源保障实施。

总    结

在第一阶段的四个月里,这套方案成功地帮助客户提升了资源利用率,年度降本超过千万人民币。同时,业务使用体验并未受到影响。我们创新性地提出通过增强 RunC 来解决问题的思路,同时得到了落地验证,也符合当下云原生走向融合的大趋势。

展    望

授人以鱼不如授人以渔,我们更期望帮助客户落地一套普适的资源能力,做到业务变化资源不需要重新调整适配。这也是第二阶段我们着重解决的问题,变用得稳为用得好。

弹性使用是王道

通常来说,业务自己评估资源使用来定义一个资源量的框,比如 4core,8G,理论上业务不具备评估资源框的能力,这就带来了评估不准的问题,少了就会 OOM,多了就会造成资源浪费。一个常见的现象:K8s 的资源已分完,但整机利用率仍然很低,同时还出现了大量容器级 OOM。那么如何解决这个问题呢?

解决思路: 当整机资源充足时,让达到限制的容器突破限制获取更多资源,同时优先结束低优先级的超卖任务,释放其他容器预分配但未使用的资源。被结束的任务本来早该结束,多运行的时间是额外收益。

总的来说,我们主张通过弹性使用资源来提高利用率,而不是要求用户自己进行评估。

Workset

研发工程师在写代码时并不能确认程序动态运行起来后内存消耗,Brendan Gregg 在文章中区分了申请内存的"usage"和实际使用的"WSS",称之为"workset"。Linux 内核中,Page Cache 就是一个例子。它会缓存访问过的文件页,减少 IO 开销,但也会占用大量内存,只在紧张时才回收。这在 IDC 服务器中会引起并发问题,如全局锁竞争,影响业务。这点在龙蜥操作系统中已有解决方法。按访问时间排序 Cache,并逐渐清理长期未用的文件页,保持内存健康。

IO Factor

IO 优化是接下来的重点。希望在这个层面去解决掉 IO wait 这种超高的现象,同理也是采用上面单机同分布式层联动的思路。这将有助于进一步提升系统性能和效率。敬请关注在这方面的进一步工作和成果。

三年疫情给经济带来很大冲击,大中小企业都在考虑降本求稳,贝联珠贯致力于成为 FinOps 领域的领导者,在控制成本方面助力企业精打细算,花好每一分钱。本次分享源自某大客户真实案例,希望给大家带来不同视角,也欢迎联系我们 (service@lccomputing.com) 开展合作。

作者介绍

王元良,贝联珠贯合伙人,负责单机系统方向的研发和 AI 方向的探索,曾就职于 H3C、阿里巴巴、字节跳动等公司,经验集中在 IoT、云 IaaS、容器、资源隔离、软硬结合以及系统稳定性。曾参与过大型网络操作系统研发,大规模混合部署研发,对资源弹性隔离,软硬一体存储优化有深刻理解。

活动推荐

QCon 全球软件开发大会·上海站将于 12 月举办,拟邀请 70 位嘉宾前来分享。此次大会策划了 LLM 落地应用、AI Agent  、Code Assistant  、业务安全  、金融科技  、信创软件集成开发环境技术  、LLM+ 质量效能 、高性能网关等方向。

本次大会以「启航·AIGC 软件工程变革」为主题,目前大会议题正在同步征集中,点击 「阅读原文」 即可查看详情。现在购票即可享受 7 优惠,立减 ¥2040。 咨询购票可联系票务经理 18514549229(微信同手机号)。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/162347
 
187 次点击