字节跳动:混布环境下集群的性能评估与优化

英特尔® 资源调配技术和英特尔® Platform Resource Manager 如何为字节跳动提升集群性能

字节跳动作者:孙殿竣,段熊春,江帆,宋牧春,尹洪波,周成明,向武

英特尔作者:沈欢星,沈晓晨,李聪,黄太,周申

  • 字节跳动在优化混布集群的性能过程中应用了英特尔® RDT 和英特尔® PRM。PRM 是一套软件包,可将不同优先级任务混布到一个节点或一个集群。RDT 是一个由多个组件功能组成的框架,用于监控及分配高速缓存和内存带宽,可以跟踪和控制平台上同时运行的多个应用、容器或虚拟机正在使用的共享资源,以确保复杂环境中关键工作负载的性能。

author-image

作者

工作负载混布背景介绍

在同一服务器上混布 (co-locate) 不同优先级的工作负载是一种提高服务器总利用率的新方法。按照传统方式,一台服务器只运行一种时延关键型工作负载,但这种方式通常无法做到 CPU 的全时段充分利用,因此为安排低优先级工作负载将这些 CPU 未用时间利用起来提供了机会。举例来说,面向最终用户的工作负载日常使用 CPU 的模式可能为:夜间使用率高,上午使用率低。在这种情况下,低优先级的任务就可以尽可能多地在上午运行,夜间则减少占用 CPU 的时间。这样操作的前提是,不违反时延关键型工作负载的服务级别协议 (SLA)。

遵守时延关键型工作负载的 SLA 对工作负载混布而言是一个巨大挑战。从上层软件到底层硬件资源,整个计算堆栈都需要做到始终能够满足高优先级工作负载的需求。例如,Linux 内核任务调度器会决定任务的运行。当时延关键型工作负载接收到突发请求时,调度器需要从混布的低优先级任务收回 CPU 时间,并尽快让关键任务运行,否则将影响该时延关键型工作负载的性能。像三级缓存和内存带宽这类底层硬件资源要想得到优先处理更是难上加难。有些工作负载运行时可能对 CPU 的占用率较低,从而留下了充裕的 CPU 时间供其他工作负载运行。但如果这些工作负载是三级缓存访问敏感型,那么工作负载的性能极易受到三级缓存缺失的影响。如果混布的低优先级任务抢占了三级缓存,则可能导致时延敏感型工作负载无法遵守 SLA。

这个问题随着 SLA 定义越来越严格而变得更加严峻。为了提供更好的用户体验,工作负载所有者会将尾时延作为其关键工作负载的 SLA。这个目标颇有难度,即使在所有计算资源都指定给一项工作负载的非混布集群中也是如此。

当集群中出现违反工作负载 SLA 的情况时,要想确定根本原因很难。集群所有者必须排查所有可能造成的影响,从软件代码变更到运行时配置,从上层资源管理到底层资源分配,逐一进行。如果一个集群中运行的工作负载达数十种,要逐一分析性能下降的原因将是一项冗长耗时的工程。而如果不知道根本原因,集群管理员就无法充满信心地采用某种缓解方案。

图 1. 字节跳动集群管理概览

字节跳动混布集群概览

字节跳动是一家位于北京的中国互联网科技公司,目前运营着多个基于机器学习的内容平台。为提高服务器总利用率,字节跳动建立了混布集群。他们利用观察到的某些工作负载的 CPU 日常使用模式,通过混布机器学习等低优先级任务来占用 CPU 的空闲时间。在字节跳动混布集群内混布的工作负载有两种:在线工作负载和离线工作负载。在线工作负载属于远程过程调用 (RPC) 服务,有着严格的 SLA 要求。而 Hadoop 任务和视频转码等多数离线工作负载则以吞吐量为导向。混布集群的目标是提高服务器总利用率,同时遵守在线工作负载的 SLA。

要维持在线工作负载的性能,需要将 CPU 资源妥善分配给离线工作负载和在线工作负载:离线工作负载须在在线工作负载发出请求时尽快归还 CPU 时间。这一过程由 cpuset 实施。所有在线工作负载都在一个 cpuset 内运行,离线工作负载在另一个 cpuset 内运行。它们并不共用逻辑 CPU 内核或物理 CPU 内核。资源控制器会根据所有在线工作负载的 CPU 负载持续调整 cpuset 配置。当所有在线工作负载的 CPU 负载增加时,资源控制器会将更多 CPU 分配给在线工作负载的 cpuset。而当 CPU 负载减少时,资源控制器会将 CPU 内核分配给离线工作负载。在一台服务器上运行的在线工作负载可能多达数十种,它们可以在在线工作负载 cpuset 中的任何 CPU 上运行,离线工作负载采用的是同一逻辑。

通过工作负载混布,服务器总利用率与非混布集群相比有所提升。但与非混布集群中的工作负载相比,在线工作负载尾时延波动较大。目前根本原因尚不明确。可能是在线工作负载与离线工作负载之间争用上层资源所致,也可能是受到了三级缓存和内存带宽等底层资源干扰的影响。唯一明确的事实是,在混布情况下性能有所下降。


共享硬件资源的干扰分析

我们对字节跳动的混布集群进行性能分析的目的在于要厘清单一在线工作负载的性能是否会受离线工作负载的影响,以及性能损失是否是三级缓存等底层硬件干扰所致。如分析结果证实影响来自三级缓存或内存带宽,我们就有很好的机会利用英特尔® 资源调配技术(英特尔® RDT)来缓解上述影响。

为评估在线工作负载是否受到了共享硬件资源上混布工作负载的影响,我们设计了一套性能分析方法。针对同一种工作负载,我们基于运行时收集的底层性能计数器创建了一个回归模型。结果显示,在线工作负载遭遇到三级缓存干扰,进而影响了工作负载的性能。基于该分析,我们认为缓存管理有助于缓解缓存对在线工作负载的干扰并确保在线工作负载的性能。


底层性能计数器

工作负载性能模型是基于底层性能计数器构建的。性能计数器是平台提供的一种记录特定硬件执行行为的硬件功能。我们从 CPU 角度选择了三种计数器作为工作负载性能的指标:unhalted CPU cycles、retired instructions、cache misses。Cycles per instruction (CPI) 指执行每条指令平均所需的 CPU 周期数量。CPI 越高意味着完成指令需要的 CPU 周期越多。当 CPI 高到一定程度时,工作负载的性能可能会受到影响。Cache misses per kilo-instructions (MPKI) 指的是工作负载每千条指令的三级缓存缺失数,用来确定 CPI 高于常规值时的根本原因。如果 CPI 和 MPKI 同时高于常规值,则表明工作负载的性能很可能已经受到缓存缺失的影响。只要密切监控一种工作负载在运行时的这些指标,我们就能知道底层共享资源对性能有哪些干扰(如有)。

在本文所述的情况中,尾时延等传统性能指标无法用于性能评估。对字节跳动而言,在线工作负载通过向其他服务发出函数调用来完成一项事务,因此其尾时延既可能受自身性能影响,也可能受其他服务完成函数调用的速度的影响。因此,我们不能用在线工作负载的尾时延来研究混布工作负载的干扰问题。

为分析字节跳动混布集群中离线工作负载的性能,我们每 30 秒针对各在线工作负载收集性能计数器、缓存占用大小 (cache occupancy) 和其他辅助指标(如 CPU 利用率和工作负载强度)。这些指标或用于建立性能模型,或用于验证分析结果。


英特尔® 资源调配技术

英特尔® 资源调配技术(英特尔® RDT)把对应用、虚拟机 (VM) 和容器使用三级缓存 (LLC) 和内存带宽等共享资源的监测和控制能力提高到了全新水平。这是在工作负载整合密度、性能一致性和动态服务交付上实现的里程碑式的飞跃,能够在提高整个数据中心效率和灵活性的同时,降低总体拥有成本 (TCO)。随着软件定义基础设施和高级资源感知编排技术在行业中影响力的不断上升,英特尔® RDT 已经成为优化应用性能以及增强使用英特尔® 至强® 处理器的编排和虚拟化管理服务器系统功能的关键功能集。

英特尔® RDT 提供了一个由多个组件功能(包括 CMT、CAT、MBM 和 MBA)组成的框架,用于实现高速缓存和内存带宽监控及分配功能(见图 2:英特尔® RDT 功能)。这些技术可以跟踪和控制平台上同时运行的多个应用、容器或虚拟机正在使用的共享资源,例如三级缓存 (LLC) 和内存 (DRAM) 带宽。英特尔® RDT 可协助开展 “吵闹的邻居” 检测,并有助于降低性能干扰,从而确保复杂环境中关键工作负载的性能。

图 2. 英特尔® RDT 功能

图 3. 英特尔® RDT 内核架构

图 3:英特尔® RDT 内核架构描述的是英特尔® RDT 功能的 Linux 内核框架和实现。核级和线程级 MSR 寄存器操作,如功能枚举、监控和分配配置、CLOS/RMID 与线程关联、读取监控计数器,均纳入文件系统操作。从最终用户的角度来看,英特尔® RDT 的监控和分配功能是通过默认装载在 /sys/fs/resctrl 下的资源控制文件系统来实现的。

英特尔® RDT 在 resctrl 文件系统中的分层结构类似于控制组 (Cgroup)。与 Cgroup 相比,resctrl 文件系统界面有着类似的进程管理生命周期和用户界面。但不同于 Cgroup 的分层结构,resctrl 文件系统界面是单层文件系统结构。

资源组在 resctrl 文件系统中表示为目录。默认组为根目录,在文件系统装载后即拥有系统中的全部任务和 CPU,可以充分使用所有资源。‘info’ 目录包含已启用的资源的信息。

启用 RDT 控制后,可在根目录中创建用户目录(“CG1” 和 “CG2”,见图 4:英特尔® RDT 在 resctrl 文件系统中的分层结构),为每个共享资源指定不同的控制力度。RDT 控制组包含以下文件:“tasks”:读取该文件会显示该群组所有任务的列表。将任务 ID 写入文件会添加任务到群组。“cpus”:读取该文件会显示该群组拥有的逻辑 CPU 的位掩码。将掩码写入文件会添加 CPU 到群组或从群组中移除 CPU。“schemata”:该群组可访问的所有资源的列表。

启用 RDT 监控功能后,根目录和其他顶层目录会包含 “mon_groups” 目录,在此目录中可以创建用户目录(“M1” 和 “M2”,见图 4:英特尔® RDT 在 resctrl 文件系统中的分层结构),以监控任务群组。“Mon_data” 目录包含一组按照资源域和 RDT 事件组织的文件。这些目录中,每个目录针对每个事件都有一个文件(“llc_occupancy”、“mbm_ total_bytes” 和 “mbm_local_bytes”)。这些文件为群组中的所有任务提供了事件当前值的计数器。

图 4. 英特尔® RDT 在 resctrl 文件系统中的监测和控制示意图

英特尔® Platform Resource Manager

英特尔® Platform Resource Manager(英特尔® PRM)是一套软件包,可帮您将尽力而为型 (best-e_orts) 任务和时延关键型任务混布到一个节点或一个集群。这套软件包包含:
 

  • 代理(eris 代理),可监测和控制各节点上的平台资源(CPU 周期、三级缓存、内存带宽等)。
  • 分析工具(分析工具),可建立平台资源冲突检测模型。


性能建模

回归模型旨在为在线工作负载建立 CPI 和 MPKI 模型。该模型利用混布离线工作负载的周期数和 CPU 总利用率来为 CPI 和 MPKI 建模。

CPI=f(CPU_cycles,O_ine_workload_utilization)
MPKI=f(CPU_cycles,O_ine_workload_utilization)

其中 f(*,*) 表示高斯分布。

该模型旨在探讨 CPI/MPKI 与影响属性之间的关系。按性质划分,CPI 和 MPKI 与工作负载强度有关。我们将离线工作负载利用率作为另一属性添加到模型中,以确定它们之间有无任何相关性。如果在同等工作负载强度下,CPI 随着离线工作负载利用率的提高而增加,则工作负载的性能很可能受到了离线工作负载的影响。如果 MPKI 有同样的相关性,则影响很可能来自三级缓存干扰。

我们为每项来自相同代码库的在线服务建立一个回归模型。CPI 和 MPKI 模型均基于七天运行时指标建立。我们将指标拆分 20 次以进行模型筛选,最后随机选择 500 个样本建立模型。我们还设计了两个测试集来检验离线工作负载利用率与 CPI/MPKI 之间的相关性。第一个测试集为不同的 CPU 周期组合,离线工作负载利用率较低。离线工作负载低利用率的抽样范围是低于总离线工作负载利用率 10%。另一测试集的样本来自离线工作负载利用率较高的不同的 CPU 周期。离线工作负载高利用率的抽样范围是高于总离线利用率 90%。将两个测试集用于 CPI/MPKI 模型是为了观察 CPI 或 MPKI 是否会随着离线工作负载利用率的提高而增加。

我们发现,对于某些在线工作负载,CPI/MPKI 与离线工作负载利用率之间存在相关性。一种在线工作负载的结果见图 5:性能、建模和结果。图中显示,离线工作负载的利用率越高,CPI 和 MPKI 值越大。我们因此得出结论,该工作负载会受缓存干扰,其性能因干扰而受到影响。

此外,我们还收集了英特尔® RDT 指标来验证此评估结果。同一工作负载的缓存占用情况显示,强度较高时,工作负载会跨越两个 NUMA 域运行。离线工作负载在其中一个 NUMA 域中高强度运行,与其他在线工作负载争夺该域中的三级缓存,最终占用了三级缓存。基于此分析结果和缓存占用指标,我们可以确定,针对离线工作负载进行缓存管理可以减少混布在线工作负载的缓存干扰。

图 5. 在线工作负载的性能、模型和结果:左:CPI 模型(离线工作负载 CPU 利用率低/高);右:MPKI 模型(离线工作负载 CPU 利用率低/高)。

集群层面部署与结果

根据分析结果,我们认为缓存干扰对混布集群中的在线工作负载性能造成了影响。为缓解干扰,字节跳动部署了英特尔® 资源调配技术来管理离线工作负载的缓存占用情况。下文所述的三种工作负载中有两种实现了性能提升。


RDT 配置

对于一台同时运行在线和离线两种工作负载的服务器来说,所有离线工作负载会受到限制,只能使用两条缓存通道,而在线工作负载则能够使用全部缓存通道。


评估范围

拥有超过 9,000 台服务器且服务器均已部署 RDT 配置的混布集群。


评估方法

在线工作负载第 99 百分位的时延波动用于指示缓存管理配置的影响。工作负载第 99 百分位的时延波动定义为:
波动t = |99th_latencyt - 99th_latencyt-1 |/99th_latencyt

在两种场景下对其进行对比:
1.    工作负载在混布集群中运行(未启用缓存管理配置)与在非混布集群中运行情况的对比。
2.    工作负载在混布集群中运行(已启用缓存管理配置)与在非混布集群中运行情况的对比。

首次收集的工作负载第 99 百分位的时延波动数据来自未启用缓存管理的混布集群和非混布集群。在混布集群中启用缓存管理配置后,再次收集相关指标。我们研究了三种在线工作负载的数据集,每个数据集用时 22 小时。


评估结果

两种样本工作负载(工作负载 A 和工作负载 B)的结果表现较好,与非混布集群相比,尾时延波动在执行缓存管理配置后得到明显改善。

工作负载 A

对于工作负载 A,混布集群中有超过 9,000 个实例,非混布集群中有超过 3,000 个实例。在不启用缓存管理的条件下,混布集群中尾时延的波动明显高于非混布集群中的尾时延波动 {见图 6a:工作负载 A(启用前)}。若在混布集群中启用缓存管理,则尾时延的波动与非混布集群中的尾时延波动相当。

工作负载 B

在混布集群中启用缓存管理后,工作负载 B 的结果同样表现较好。工作负载 B 在混布集群中有超过 10,000 个实例,在非混布集群中有超过 5,500 个实例。图 7a:工作负载 B(启用前)所示为该工作负载在混布集群中运行(未启用缓存管理)与在非混布集群中运行的尾时延波动情况。可以明显看出,混布集群中的波动明显高于非混布集群中的波动。图 7b:工作负载 B(启用后)所示为在混布集群中启用缓存管理后的对比。两集群中尾时延波动的差距不再那么明显。

图 6a. 工作负载 A(启用前):工作负载 A 在非混布集群和未启用缓存管理的混布集群中的尾时延波动情况。

图 6b. 工作负载 A(启用后):工作负载 A 在非混布集群和启用缓存管理的混布集群中的尾时延波动情况。

图 7a. 工作负载 B(启用前):工作负载 B 在非混布集群和未启用缓存管理的混布集群中的尾时延波动情况。

图 7b. 工作负载 B(启用后):工作负载 B 在非混布集群和启用缓存管理的混布集群中的尾时延波动情况。

结论

字节跳动利用英特尔® RDT 和英特尔® Platform Resource Manager 来缓解底层硬件资源对其混布集群的干扰。他们发现,时延关键型工作负载在混布集群中会出现性能降级的情况,因此首先设计了一个回归模型来分析时延关键型工作负载是否受混布的低优先级任务的影响以及如何被影响。分析结果显示,在线工作负载会受三级缓存干扰。在对低优先级任务执行缓存管理策略后,关键工作负载的性能有所恢复,可以与在非混布集群中的性能相媲美。这证明英特尔® RDT 和英特尔® PRM 可以减少工作负载混布时底层资源对时延关键型工作负载的干扰,进而提高基于英特尔® 至强® 平台的字节跳动混布集群的服务器总利用率。


获取更多信息的途径

有关英特尔® RDT 的更多信息,请参阅:https://www.intel.cn/content/www/cn/zh/architecture-and-technology/resource-director-technology.html

有关英特尔® RDT 在 resctrl 文件系统中的分层结构的更多信息,请参阅:https://www.kernel.org/doc/Documentation/x86/resctrl.rst

有关英特尔® Platform Resource Manager 的更多信息,请访问 https://github.com/intel/platform-resource-manager 或者联系 shen.zhou@intel.com。