1. 论文信息
所有作者及单位
- Johannes Weiner, Niket Agarwal, Dan Schatzberg, etc. Mate Inc.
- Dimitrios Skarlatos, 卡内基梅隆大学CMU
2. Background
机器学习等新兴应用对内存需求的大幅增长,加上DRAM设备扩展速度的放缓[19,25] 以及DRAM成本的大幅波动,使得DRAM作为唯一的内存容量解决方案变得昂贵得令人望而却步。
近年来,大量非DRAM更便宜的内存技术,例如NVMe SSD[8,11]和NVM[14,17,24,30,34,37]已成功部署在数据中心,或正在使用它们方式。此外,新兴的非DDR内存总线技术,例如CXL[9]提供类似内存的访问语义和接近DDR的性能。这些趋势的融合为内存分层带来了过去不可能的新机会[12,16,21,31–33,39,40]。
使用压缩内存可以大幅降低成本,但这仍然不够,我们需要NVMe SSD等替代内存技术来进一步降低成本。
3. 解决了什么问题
性能不变的情况下,节约内存。TMO根据设备的性能特征和应用程序对内存访问速度减慢的敏感度,自动调整要卸载到异构设备(例如压缩内存或SSD)的内存量。
4. 其他学者解决这个问题的思路和缺陷
zswap是一项Linux内核的虚拟内存压缩功能,可为将要交换的页面提供压缩回写缓存。当内存页将要交换出去时,zswap不将其移动到交换设备,而是对其执行压缩,然后存储到系统RAM内动态分配的内存池中。回写到实际交换设备的动作则会延迟,甚至能完全避免,从而显著减少Linux系统用于交换的I/O;副作用则是压缩所需的额外CPU周期。
唯一已知的大规模采用内核驱动交换用于延迟敏感的数据中心应用程序的是Google的zswap部署[18][43].在本文的其余部分中将其称为g-swap。作为先驱,g-swap极大地推进了现有技术水平,但仍然存在几个主要局限性:仅支持单个慢速内存层;某些应用程序的数据难以压缩,例如具有量化字节编码值的机器学习模型。
5. 围绕该问题作者如何构建解决思路
TMO需要回答两个问题:要卸载多少内存以及要卸载哪些内存。
(1)页面会冷多久:
service-level agreement SLA 网站服务可用性的一个保证
为了简化数据中心中应用程序的操作,需要使用大量内存来启用微服务并提供基础设施级功能。我们将软件包、分析、日志记录以及与数据中心应用程序部署相关的其他支持功能所需的内存定义为数据中心内存税。这部分占20%,最先被卸载,因为内存税的SLA比程序直接消耗的SLA少。
(2)不同程序文件页和匿名页所占比比例不同
(3)考虑到卸载到的SSD耐久性不同SSD设备的延迟等,设计架构
图6显示了TMO架构概述(左)以及内存和存储布局(右)。
- 未修改的工作负载在容器1内执行,并通过系统调用和分页与内核内存管理子系统交互。
- Senpai是一个用户空间组件,负责控制内存卸载过程并决定应从每个工作负载中卸载多少内存。Senpai以压力信息的形式监控应用程序性能下降。
- 压力信息由内核中的压力失速信息(PSI)组件报告。
- 基于PSI信息Senpai通过写入cgroup控制文件来驱动卸载过程,从而触发内核的内存回收逻辑。回收逻辑决定要卸载哪些内存。
- 内存管理子系统向PSI模块暴露内存压力信息。
- 5触发对卸载后端和常规文件系统的读写操作。
TMO支持卸载到基于zswap的压缩内存池或通过交换存储设备。
5.1 PSI有效捕获内存卸载对不同应用程序的影响
每个非闲置进程,PSI会进一步区分进程可运行的时间段和因资源不足而停滞的时间段。将计算潜力定义为以CPU数量为上限的非闲置进程数量。PSI=停滞数/计算潜力*100%. 对于容器和全系统域,PSI为每种资源引入了两个压力指标,分别称为 “some”和 “full”。some指标跟踪域内至少有一个进程在等待资源时停滞的时间百分比。full指标跟踪的是所有进程同时延迟的时间百分比。
虚线框是执行时间和停顿时间。执行时间标准化为100%并分为四个部分。some停顿蓝色箭头,full停顿绿色箭头。第一阶段A和B停止其中一个即可都有资源用some指标12.5%;第二阶段同时停止6.25%,full指标6.25%,some指标18.75%。“some”旨在捕获由于缺乏资源而导致各个进程增加的延迟,而“full”则表示容器或系统中完全非生产性的时间量。
PSI只出现在以下3个场景:
为了跟踪内存压力,PSI记录专门在内存不足时发生的事件所花费的时间。目前,这包括三种情况。第一种情况是当内存已满时进程触发回收页面并且进程尝试分配新页面。第二种情况是进程需要等待IO发生故障,即最近从文件缓存中逐出的页面出现重大故障。第三种情况是进程在从交换设备读取页面时发生阻塞。
在PSI之前,操作员依赖于关联内核时间、应用程序吞吐量变化、回收活动事件计数器、文件重读和换入等间接指标来估计工作负载的资源健康状况。这需要对存储硬件设备特性和内核行为有直观的了解。例如,文件超前读取算法可能会在不同程度上使应用程序免受已记录的缓存重读的影响。另一方面,PSI可直接在进程级别测量合格停滞事件造成的生产力损失。它考虑了底层硬件的差异、内核内存管理算法的有效性,甚至工作负载的内部并发性(即部分停滞与完全停滞)。
所以这个指标反应资源总数变化的情况下,对每个进程性能的影响。仍然是对某个进程/程序,我按量分配DRAM,看他性能提高了,再给一点,
而且从热力图来看,热度的提升是有一定时间的。
5.2 Senpai
每隔几秒,Senpai就会为每个cgroup计算一次要回收的内存量,如下所示:
𝑃𝑆𝐼𝑡ℎ𝑟𝑒𝑠ℎ𝑜𝑙𝑑和 reclaim_ratio是可配置参数。 𝑐𝑢𝑟𝑟𝑒𝑛𝑡_𝑚𝑒𝑚 是cgroup的当前内存占用量。
动态工作负载在某些情况下可能会导致问题。例如,如果容器内存快速增长且其大小正在主动扩展,则它可能会被阻塞,直到 Senpai进一步提高其限制。为了解决这个问题,我们在内核中添加了一个无状态内存回收cgroup控制文件。通过这个控制钮,Senpai可以要求内核精确回收计算出的内存量,而不施加任何限制,从而避免了阻塞扩展工作负载的风险。(看不懂这个解决方案哩)
Senpai在导出内核之上的用户空间中以PSI和cgroup内存控制接口实现。与假设的内核内实现相比,这有几个优点。首先,用户空间可以完全访问浮点单元,因此可以更有效地执行计算。其次,用户空间组件的发布周期往往比内核快得多。计划在具有不同性能SLO阈值的工作负载中利用不同的Senpai配置。
5.3 回收操作
Senpai依靠内核从cgroups中回收冷内存页。Senpai让内核的回收算法选择要卸载的页面,而不是使用昂贵的全页表扫描来确定哪些内存页面是冷页面。该算法通过为文件和交换支持页面维护一对活动/非活动页面LRU列表,并首先回收较冷的页面来运行。这种机制经过生产测试,能以相对较低的CPU成本和较高的准确性识别较少使用的内存页面。在Senpai中使用这种机制大大简化了我们的实现过程。在生产中,Senpai驱动的回收只消耗所有CPU周期的0.05%,可以忽略不计。
但是有改进。由于很多文件只会被读一次,当文件缓存缺页时,换进来的Page会优先放在inactive list中。当再次读到这个页面时,按照soft fault的惯例,页框会从inactive 挪到active。Linux中使用radix tree来追踪页框,radix tree通过一种特殊的元素来追踪匿名内存被换到swap中的情况。作者扩充了这个特殊的元素,称之为shadow entry。当inactive list中的内容被换出时,有个计数器(workingset_time)会自增。每个页框被移除的时候,shadow entry中都会记录当前的workingset_time。也即当第一个被reclaim的页面对应的shadow entry记录0,第二个被reclaim的页面记录1,等等单调自增。
当某个被reclaim的页面发生PF被换回时,用当前的workingset_time减去shadow entry中记录的值可以得到页面被换出期间清理了多少页面,称之为refault distance。如果refault distance小于active list,则当前这次PF就被认为是refault。当发生refault时,内核就会开始倾向于回收匿名页。同时发生refault的页面会直接加入到active list并使active list 长度加一。当refault distance小于active list时,其实就说明这个页面使用的比较频繁,这时候我们就应该扩大一点active list把这个页面加到acitve list中,并且转向回收匿名内存。
6. 从结果看,作者如何有力证明他解决了问题
7. 缺陷和改进思路
8. 创新点
这篇文章主要是为了卸载冷数据,提出的指标很新颖也有效。而且这是关注内存和硬盘之间交互的,也挺有参考价值。
9. 积累
迁移过程可以由应用程序本身、用户空间库[6,12,26,29]、内核或虚拟机管理程序驱动。
我们将内存卸载后端定义为保存卸载内存的慢速内存层。在我们当前的生产队列中,这由NVMe SSD和压缩内存池组成。未来我们预计这将包括NVM和CXL设备。
在跨卸载后端具有多样性的异构存储器系统中,给定的主要故障率(那些硬件计数器)可能在慢速存储设备上构成问题,而在较快存储设备上则无关紧要。一般来说,很难理解特定的内核事件是否是工作负载的功能问题。