论文发表于 SC-W 2023,Paper,元数据论文阅读汇总 “Adaptable I/O System (ADIOS)” 自适应I/O系统 “Distributed Asynchronous Object Storage (DAOS)” 分布式异步对象存储 “persistent memory (PMEM)” 持久存储器

背景

在HPC中,应用程序之间的数据移动通常由I/O中间件来促进,例如自适应I/O系统(ADIOS)。此中间件利用底层存储服务的功能来促进数据移动和分发。最近的存储系统Intel DAOS承诺提供新的功能,以在新兴的内存/存储系统上实现性能和可扩展性。DAOS已经部署在剑桥大学、TACC和即将推出的Aurora超级计算机中。本文研究了在许多不同的DAOS接口和数据模型中映射ADIOS的性能权衡,并提出了有效使用它们的建议。

随着HPC中的数据量呈指数级增长,I/O成本已成为一个日益增长的瓶颈。为了增加I/O带宽和支持高级别的并发性,已经付出了大量努力。然而,I/O挑战中一个不太受重视的部分是HPC中元数据的处理[1]。随着应用程序的规模和复杂性的增长,元数据的大小和数量也在增长。最近的研究表明,元数据可以对HPC I/O的整体性能产生重大影响[5]。此外,元数据带来的挑战不能简单地通过添加更多的硬件资源来克服。我们预计,随着我们进入EB时代,这种趋势将持续下去,尤其像Aurora超级计算机这样的机器将非常突出。

DAOS

分布式异步对象存储(DAOS)是一种为持久内存设计的开源对象存储。旨在为PMEM提供低延迟、高带宽的访问,并针对数据中心、传统HPC和AI/ML工作负载等各种用例。由于其快速持久性,它被设计为使用Intel Optane,支持延迟敏感的小型I/O和元数据。除了NVMe驱动器之外,还可提供额外的容量和原始带宽,开放接口还用于提供对Optane和NVMe的低延迟访问。DAOS中的数据路径完全在用户空间中,通过远程直接内存访问(RDMA)提供零拷贝,并且它本身提供了一个对象接口,在该接口上提供了POSIX、MPI-IO和HDF5等中间件层。

DAOS目标。每个DAOS服务器节点中的PMEM和NVMe存储被划分为多个DAOS目标。每个DAOS套接字都有一个DAOS引擎守护进程,用于处理到这些目标的I/O。DAOS对象分布在这些目标上以提供性能和恢复能力。

DAOS对象。DAOS提供Key-Value(KV)和数组对象。

KV:提供put、get操作,其中Value是可变长度的数据块。一个KV对象可以存储许多KV对。Key用于数据访问,还可以控制将Value放置在哪个存储目标中。

数组:提供逻辑一维数组抽象。每个DAOS数组都有固定的单元大小和块大小,它们是在创建时定义的。块大小是切换到下一个目标之前,存储在当前目标中的元素的连续数量。单元大小是单个元素的大小。块中的所有元素都位于同一个DAOS目标中。我们使用DAOS阵列写入和读取接口,这两个接口都提供矢量I/O支持,允许在单个调用中从阵列的多个段进行I/O。

基于DAOS文件系统(DFS)的DAOS POSIX仿真。DFS提供了一个支持文件和目录抽象的分层POSIX命名空间。DFS文件本质上是使用块大小为1MB、单元大小为1字节的DAOS阵列来实现的。仿真的POSIX命名空间通过FUSE守护进程向应用程序公开。带有LD_PRELOAD的拦截库为POSIX读/写调用提供了完整的操作系统旁路。

ADIOS

ADIOS是用于HPC I/O的中间件库,它为应用程序提供了高级数据抽象,同时隐藏了低级细节,例如:如何在应用程序内存与HPC网络/文件/广域网/直接内存访问介质之间高效传输/存储/检索数据。ADIOS特别关注在领先的HPC计算资源上,为要求最高的EB级应用程序提供完整的存储/网络带宽。虽然ADIOS能够进行在线代码耦合(例如,同时运行的数据源和接收器之间的直接连接),但本文将重点关注稳定存储的I/O。

ADIOS的I/O抽象是集体的、基于时间步长的,读取器和写入器列组通过Begin/EndStep调用同步它们的活动。在每个I/O时间步中,应用程序可以将数据放入存储器或从存储器中取出,每个操作都寻址一个预先声明的ADIOS变量。变量可以是来自命名的单个(原子)值或大型多维数组的几个ADIOS数据结构中的任何一个,这些数据结构可以在基于MPI的应用程序的各个列中分解。

ADIOS元数据。由于ADIOS读者语义允许数据发现,每次ADIOS操作写入数据时,还会生成ADIOS元数据,用来描述已输出的变量的名称、类型、维度、ADIOS全局阵列空间中数据块的虚拟位置(开始和计数)、以及存储数据块的物理位置和大小。为了满足ADIOS中的Get请求,每个读取器列组都必须访问该时间步长上每个写入器列组生成的完整元数据集。这意味着,虽然实际的数据读取是根据应用程序的需要以不同的模式进行的,但元数据交换具有可预测性。

ADIOS中的元数据传输。如图1所示,在现有的ADIOS POSIX引擎中,所有写入器列生成的元数据,在每个时间步长都合并在列0上,然后写入到专用的元数据文件中。在读取器端,列0从写入器检索所有元数据,并通过MPI广播将其分发给其余的读取器列。

为了探索基于DAOS的元数据引擎设计中的性能和权衡,我们建立了元数据从写者到读者传输的相关指标。

元数据稳定时间:包括从元数据创建,到写者将其放入稳定存储的所有时间,以确保其持久性和可用性。 元数据获取时间:从稳定的存储中检索元数据,并确保每个读者列可访问的时间,使他们能够访问和利用信息。 元数据端到端传输时间:稳定和获取时间之和。

由于我们的重点是大规模数据,我们只关注每个时间步长的重复元数据传输成本,不包括任何一次性成本。

本文工作

对ADIOS元数据引擎和DAOS之间的交互进行了研究,强调了这两种技术协同工作的可能性和挑战。证明了围绕POSIX语义构建ADIOS元数据是困难的,以及对大规模环境中元数据端到端传输时间的实质性影响。 评估了新构建的基于ADIOS DAOS对象的元数据引擎的元数据稳定性和获取时间。 新的基于DAOS阵列的引擎,在大规模上提供比POSIX快3.5倍的ADIOS元数据端到端传输时间。

具有DAOS对象的ADIOS元数据引擎

设计决策

DAOS主要支持两个基于对象的接口:键值(KV)和数组。在利用这些接口进行元数据存储和检索时,做出了一系列关键的设计选择。

在最初的设计决策中,我们考虑了三种将写入器列组的元数据映射到DAOS对象的选项:每个写入器列一个对象,每个时间步所有写入器列共享一个对象,每个写入器列在所有时间步使用单个对象。对于大规模的模拟,前两个选项将需要将所有DAOS对象ID信息传输到读取器,从而导致额外的开销。此外,它可能会使DAOS对象元数据管理系统过载。因此,我们选择了第三种。

在读者端,元数据是否可以由每个列同时读取,而不是将其委托给列0并进行广播?我们最初的实验表明不可行,因为并发性随着写入器数量的增加而呈指数级增长。因此,我们推迟使用读取器列0,就像在ADIOS POSIX引擎中一样。

下一个要决定布局。在DAOS数组的情况下,与每个时间步长相关联的元数据从定义良好的偏移量开始,写入器利用MPI集体根据排名顺序就偏移量达成共识。使用DAOS KV,每个写入器列都将其元数据与唯一的密钥字符串放在一起。

最后,DAOS数组和KV中I/O方法的使用具有不同的语义。DAOS数组读取是矢量化的,所有编写器的所有元数据都可以同时从DAOS数组的不同部分读取。然而,DAOS KV需要单独的Get请求,当同步发出时,随着写入程序数量的增长,这些请求的成本非常高。然而,以100个为一批的异步方式执行Get,实现了良好的性能。

ADIOS 的 DAOS KV 引擎

整体流程如图2所示。DAOS KV对象由写入器列0创建,其对象ID被广播到所有其他写入器列,这是在引擎初始化期间完成的一次性设置。之后,在每个时间步结束时,每个写入器使用DAOS_KV_put() 将其元数据作为单独的键值条目存储到同一DAOS KV对象中。Key是字符串“StepN-RankID”,Value是元数据缓冲区。

读卡器l列0读取所有元数据分为两步。首先,它使用daos_kv_get() 读取每个写入器列的元数据大小,使用“StepN-RankID”作为具有NULL值缓冲区的密钥。知道了元数据的总大小后,列0就会分配内存。其次,它使用daos_kv_get(“StepN-RankID”, metadata_buffer) 读取实际元数据。然后将此元数据广播到所有其他读取器列。

ADIOS 的 DAOS 数组引擎

整体流程如图3所示。写入器列0在引擎初始化期间创建一个DAOS数组对象,然后使用广播操作将其对象ID与其他列共享。类似于DFS,块大小和单元大小分别被设置为1MB和1字节。它还创建了一个DAOS KV对象来存储元数据大小。此设置只执行一次。在每个时间步,每个写入器列都使用MPI_Allgather() 相互共享元数据大小。接下来,所有写入器都按列顺序计算它们在DAOS数组中的偏移量,并使用DAOS_array_write() 写入元数据。写入器列0使用daos_KV_get(“StepN”,list_metadata_sizes) 在KV对象中存储元数据大小的列表。

读取器列0从KV对象中读取list_metadata_sizes,并计算总元数据大小。然后,它分配内存,使用DAOS_array_read() 从DAOS数组读取所有写入器连续放置的元数据。最后,将数据广播到所有其他的读者器列。

实验评估

目标

列的数量如何影响元数据的稳定和获取时间? 元数据大小对稳定和获取时间的影响是什么? 在最大限度地减少大规模元数据端到端传输时间方面,稳定时间和获取时间之间的权衡是什么? 用于元数据传输的最高效的DAOS引擎是什么?

实验准备

所有实验都是在剑桥数据驱动发现服务(CSD3)的冰湖集群上进行的。计算节点有两个插槽,每个插槽有38核Intel®Xeon®Platinum 8368Q CPU,工作频率为2.60GHz,DRAM为512GB。网络由Mellanox HDR200 Infiniband支持。

池模式下的DAOS v2.2是用十台服务器建立的。每台服务器有两个插槽,32核Intel(R)Xeon(R)Platinum 8352Y CPU@2.20GHz。每台服务器配备2个2.1 TB PMEM存储,由256GB Optane DIMM组成。每台服务器有16个NVMe驱动器,每个驱动器的容量为3.8TB。每个服务器都配备了2个HDR200 IB。

方法论

实验设计:执行了100个时间步长的ADIOS写入器列和读取器列。写入器列和读取器列的数量从66、256到4256不等(允许的最大值),使用了多达56个计算节点来跨越广泛的范围。

元数据大小配置:我们通过更改ADIOS变量和ADIOS数组的数量,调整每个写入器列每个时间步长的元数据大小。因此,我们为E3SM配置了56KB的元数据大小,为小元数据配置了5KB的元数据大小。E3SM模拟地球的气候和环境过程,以其重要的ADIOS元数据生成而闻名。由于每个写入器列的元数据保持不变,因此传输的元数据总量会随着列的增加而增加。

测量:在ADIOS中,我们使用Caliper在DAOS引擎的EndStep()和BeginStep() 分别捕获元数据的稳定时间和获取时间。Caliper是HPC中程序检测和性能测量的框架。由于ADIOS写入器跨时间步长生成的元数据几乎相同,因此报告的时间是100个时间步长内每个列的平均时间。

数据分析:考虑到不同的元数据大小,聚类堆叠条形图描绘了跨列的元数据端到端传输时间。分析的重点是稳定和获取时间,检查单个时间步长内的I/O大小、I/O数量、布局和DAOS对象API使用等因素。

元数据端到端传输时间

中等的元数据大小,56KB,真实应用程序。总体来说使用DAOS数组更快,因为在写入时是并行的。同时将数组大小对齐时,数据分布更优,进一步加快速度。

文章里没具体写是怎么对齐的,猜测是每个写入器一个1MB的DOAS目标,每次写入时不同写入列都写在不同存储空间,因此减少了争用。但这样是否会导致大量空间的浪费?每个列只写入56KB元数据,但需要申请1MB空间,类似空间换时间的思路。

较小的元数据大小,5KB。使用DAOS 数据+对其速度最快。和之前的结果类似,感觉存储空间没有很大时,还是用异步KV更好。

经验教训

DAOS POSIX因为序列化导致稳定时间长,DAOS Array和KV都可以通过并行来加快稳定时间,与DAOS-POSIX相比,可以提供几个数量级的加速。

DAOS Array的稳定时间受到少数较小元数据的负面影响,元数据写入程序被连续放置在DAOS Array块中,导致紧密地封装了小片段,减少了DAOS目标的使用数量。因此,对这些DAOS目标的资源争用增加了。

DAOS-Array-1MB-aligned 将块划分为1MB,将元数据写入分到每个块中,改善数据分布并减少资源争用。因此,DAOS-Array-1MB-aligned的稳定时间是DAOS Array的10倍,对于较小的元数据大小,与DAOS-KV相当。获取时间由读取器列0的元数据读取时间组成,没有由于并发而引起的争用。DAOS Array读取是矢量化I/O,可以一次读取所有元数据,优于异步DAOS KV以100为一组进行批处理。

推荐:DAOS-Array-1MB-aligned在规模从几KB到数百KB的元数据大小之间提供了最佳的元数据端到端传输时间。在我们的实验中,它比异步DAOS KV 快2倍,比DAOS-POSIX快3.5倍。

总结

利用DAOS数组和DAOS KV,优化ADIOS任务的元数据的写入和读取时间。提出通过并行可以加快速度,进一步通过存储空间对齐减少元数据写入的争用。

局限性:整体看下来很简单,因为是短文实验也不太充分。具体争用的原因也没有分析,可能是锁?这里应该有不少优化空间。

好文推荐

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。