1.摘要
在多租户系统中,分布式文件系统 (DFS) 的 CPU 开销越来越成为应用程序性能的负担。 CPU 和内存干扰会导致应用程序和存储性能下降和不稳定,尤其是操作延迟。 最近用于持久内存 (PM) 的客户端本地 DFS 加速了这一趋势。
本文提出 LineFS,一个 SmartNIC 卸载的高性能 DFS,支持客户端本地 PM。 为了充分利用 SmartNIC 架构,我们将 DFS 操作分解为可以卸载到 SmartNIC 上的并行数据路径执行流水线的执行阶段。 LineFS 将 CPU 密集型 DFS 任务(如复制、压缩、数据发布、索引和一致性管理)卸载到智能网卡。 我们在 Mellanox BlueField Smart-NIC 上实施 LineFS,并将其与最先进的 PM DFS Assise 进行比较。 LineFS 将 LevelDB 中的延迟降低了 80%,将 Filebench 中的吞吐量提高了79%,同时在主机系统故障期间提供了扩展的 DFS 可用性。
2.背景
DFS 消耗 CPU 和内存资源。 当网络和存储设备相对于 CPU 提供的性能较慢时,这种消耗是微不足道的。 目前,网络和存储设备的性能正在提高,而 CPU 性能在每核性能和核数方面都停滞不前。 因此,CPU 周期和内存带宽已成为宝贵的商品。 特别是,现代 PM 优化的 DFS 与应用程序共享 CPU 和内存资源,以减少 PM 访问延迟。 不幸的是,这些系统提供的低延迟访问伴随着 CPU 与应用程序竞争的成本。
2.1Client-local DFS
客户端本地 DFS 的以下四个文件系统任务会导致高 CPU 使用率和性能干扰:
- 数据移动和索引。 文件系统调用线程来进行数据移动和组织。例如,Assise 的 SharedFS 创建了许多线程来将文件系统更新应用到 PM 并创建索引结构以优化以后的读取。
- 副本复制。为了可用性,客户端本地分布式文件系统在客户端节点之间复制数据,需要调用 DFS 服务来接受和保存每个客户端副本的数据。 副本复制会消耗内存和 CPU 资源。
- 远程存储访问请求。 并非所有文件系统请求都可以在本地提供服务,因此需要远程节点以低延迟为这些请求提供服务。 高优先级文件系统处理中断共同运行的应用程序,在频繁操作时涉及高上下文切换成本。
- 文件系统一致性。为了允许多个客户端访问具有一致性保证的共享文件系统状态,分布式文件系统必须协调这些客户端,需要在多个客户端节点上调用协调机制,通常具有低延迟要求。
2.2卸载到SmartNIC
通过将DFS业务卸载给SmartNIC可以解决上述问题。SmartNICs是位于应用程序的网络数据路径中的通用计算平台。它们的位置使它们非常适合于网络服务的卸载,包括分布式文件系统。的确, 各种SmartNIC平台提供的特性特别有助于分解存储协议的卸载,例如NVMe-oF。然而,SmartNIC卸载并不是万灵药。一些挑战使得分布式文件系统功能的卸载特别困难。
- 增加主机内存访问的延迟。 SmartNIC 是 PCIe 扩展卡。 PCIe 是一种相对于 CPU 喜欢访问内存的 DDR 内存互连的高延迟互连。 从主机 CPU 通过 DDR 访问 PM 会产生 100 ns 的延迟,而通过 PCIe 访问 PM 有几个us的延迟——一个数量级的差异。 因此,从 SmartNIC 访问存储在主机内存中的 PM 和相关文件系统状态具有很高的开销,并且需要最小化此类访问或需要隐藏延迟。
- 有限的执行环境。典型的 SmartNIC 功率范围为 25W。与功率大一个数量级的主机 CPU 相比,没有强大的内存或处理功能的空间。 SmartNIC 通常选择具有许多低频内核和少量高速缓存的小型处理器架构。
- Mellanox BlueField。 本文使用 Mellanox BlueField MBF1M332A SmartNIC探索 DFS 卸载。 这是一个 2×25GbE 智能网卡,包含一个 ARMv8 Cortex-A72 处理器,具有 16 个内核,运行频率为 800MHz。 每个 Cortex-A72 内核都有一个 32KB 的 L1 数据缓存。 两个内核共享 1MB 的 L2 缓存,所有内核共享 6MB 的 L3 缓存,以及 16GB 的内存,可能是 DRAM 或 NVDIMM-N PM。 BlueField 在 Cortex-A72 上运行 Linux。
3.LineFS设计
LineFS 是为使用 PM 和 RDMA 的节点集群设计的 DFS。 LineFS 通过谨慎地将 DFS 操作卸载到 SmartNIC 来最大限度地减少主机 CPU 开销。 LineFS 具有以下设计目标。
- 最小化主机性能干扰。应用程序和存储系统的性能和性能可预测性受到共享资源竞争的影响。 CPU 是现代云服务器中最受限制的资源之一。 LineFS 必须尽量减少应用程序和 DFS 之间对 CPU 的竞争。 为此,LineFS 将 DFS 功能卸载到 SmartNIC。
- 最大限度地减少卸载造成的减速。 LineFS 必须最小化 DFS 卸载到 SmartNIC 的性能影响。 为此,LineFS 重新考虑文件系统数据路径以利用细粒度数据并行性。 LineFS 在后台执行数据路径以允许前台主机计算继续不受影响。
- 利用数据路径处理机会。 LineFS 应利用 SmartNIC 的数据路径处理能力来机会性地执行语义感知数据转换。 利用备用的 SmartNIC 处理能力来执行数据压缩,从而节省用于复制的网络带宽。
- 提高可用性。 LineFS 还应利用 SmartNIC 的数据路径处理能力来提高 DFS 可用性。 虽然 SmartNIC 和主机 CPU 共享主机电源,但 SmartNIC 提供独立的执行环境并且可以继续运行,即使主机操作系统出现故障。
3.1 总体架构
LineFS架构。像Assise和Orion一样,LineFS采用client-local DFS模型,在客户端机器上执行DFS功能,以避免PM访问的客户端-服务器通信延迟。此外,LineFS小心地在主机和SmartNICs之间分配DFS组件。LineFS节点由两个组件组成:LibFS和NICFS。LibFSes被链接到运行在主机端Core的应用程序进程(LineFS客户端),NICFS在SmartNIC上运行。
3.2 设计原则
单纯的DFS卸载到SmartNIC会导致严重的性能下降,如果直接通过SmartNIC卸载Assise的单节点SharedFS组件,由于低效的SmartNIC执行,与基于主机的版本相比,吞吐量下降了30多倍。这是由于SmartNIC架构和PCIe之间的数据移动。为了避免卸载的开销,LineFS遵循两个设计原则:持久化和发布和流水线并行性。
- Persist-and-publish。LineFS分配一部分PM作为每个客户端PM日志。LibFSes将数据和元数据更新保存到主机上的私有PM日志中。日志被异步发布到主机-本地公共PM,并由NICFS复制到远程PM。这种持久化和发布的设计灵感来自于Strata的日志和分析方法,使LineFS能够清楚地将PM延迟的关键操作与那些可以延迟的操作分开。在LibFS使用快速主机核使主机PM日志中的数据和元数据持久后,NICFS使用SmartNIC核在后台发布和复制更新,使主机核免于执行文件系统管理任务。
- 流水线并行。LineFS利用流水线并行性来发布和复制日志。LineFS将DFS操作组织到不同的执行阶段,以构造一个执行流水线。LineFS将一组日志条目定义为一个LineFS块,通过流水线并行地处理每个块。LineFS协调流水线来线性化共享更新。
流水线并行性提供了一种方便的方法来管理并行度。为了执行每个流水线阶段,NICFS在启动时为每个阶段分配一个线程。当LibFS日志增长到LineFS块的大小(例如,4MB)时,LibFS向NICFS发送一个RPC来启动流水线。NICFS监视每个阶段所花费的时间。如果一个阶段变成瓶颈,(例如,它的等待队列超过5个条目),NICFS动态分配更多的线程来处理这个阶段。这些原则不仅可以避免开销,还可以在卸载时保持一致性,流水线并行允许LineFS按照客户端日志顺序处理数据,提供线性化和前缀崩溃一致性。
3.3 LibFS低延迟PM IO
为了提供低延迟 PM IO,LibFS 将数据保存到主机 PM 中的操作日志中。操作日志为PM中持久化(元)数据提供了一种紧凑的方式。LineFS将PM的一部分作为持久写日志分配给每个LibFS。LibFS拦截应用程序的POSIX文件系统调用,并将文件数据和元数据写入PM日志。例如,在create()系统调用时,LibFS将更新的inode节点和目录写入PM日志。对于PM来说,日志是有效的,因为PM的顺序性能很高,并且日志追加是顺序的。
读取是一个两步的过程:1)LibFS搜索它的客户端私有日志(数据还没有发布) 2)如果在日志中没有找到数据,它搜索公共PM。读路径在主机CPU中执行,不涉及NICFS。写入只需要与NICFS进行异步通信来发布和复制客户端私有日志。
3.4 DFS流水线操作
NICFS运行两个不同的流水线:发布流水线和复制流水线。发布流水线由四个阶段组成:获取、验证、发布和确认。复制流水线也由四个阶段组成:获取、验证、传输和确认。两个流水线都必须将日志数据获取到NICFS并对其进行验证。为了避免冗余数据移动,发布和复制流水线共享前两个阶段—即它们对相同的数据进行操作。在前两个阶段之后,他们会运行自己的流水线阶段。
3.4.1发布客户端日志
NICFS在后台将客户机私有日志条目发布到公共PM。在发布日志条目之后,LibFS会回收日志条目,以便为进一步的更新腾出空间。发布日志条目涉及从客户机私有日志到公共PM的内存密集型数据移动。
基本原理:LineFS将日志发布到智能网卡有四个原因:(1)减少主机CPU的占用和数据移动的负载;(2)减少DFS服务带来的调度和上下文切换开销;(3)在日志满且主机CPU资源不足的情况下,减少日志写的行首阻塞;(4)启用辅助任务,如压缩,无需CPU争用。
挑战:SmartNIC的高效卸载有两个挑战:(1)PCIe延迟高;(2)权限检查和验证(例如,防止DFS命名空间中的目录循环)会消耗足够的计算带宽,使相对弱小的SmartNIC处理器饱和。通信延迟和计算负载的双重挑战表明,重叠这些延迟有助于降低它们对端到端系统性能的影响。
方法:持久化和发布模型允许NICFS在后台发布客户端私有日志,同时应用程序继续执行。为了分摊PCIe传输开销,LineFS将连续的更新-批量到LineFS块中(batch)。一旦LibFS积累了一个LineFS更新块,它就向NICFS发送一个异步RPC请求,以开始发布该块。
如图2所示,发布流水线由四个阶段组成(阶段的主要资源在括号中):获取(PCIe)、验证(计算)、发布(PCIe和计算)和确认(PCIe延迟)。NICFS获取LineFS块到SmartNIC的内存并验证它。通过验证之后,NICFS发布LineFS块并向LibFS确认它。
通过PCIe发布数据块会导致过度的延迟,导致流水线停止。因此,LineFS在主机操作系统中使用内核工作线程来启动异步主机DMA来发布LineFS块。DMA复制仍然可以避免CPU占用,而不是使用主机Core复制PM。
3.4.2 复制流水线(x)
LineFS使用RDMA将客户端私有日志链复制到许多副本中,提供了副本之间的可用性和强一致性。与其他DFSes一样,fsync()保证了文件数据和元数据的持久性和复制。在复制链中,每个副本将主服务器的客户端私有日志保存到其本地日志中。当主节点收到来自所有副本的ack时,fsync()返回。因此,主副本和所有副本具有相同的更新视图。
对于强一致性,复制延迟直接影响DFS的写性能。反过来,有两个因素主要影响复制延迟:(1)网络(RDMA)请求处理延迟(2)DFS复制操作和协同运行的应用程序之间的CPU争用。基于主机的提供低复制延迟的方法通过将网络操作预先发送到RDMA QPs和在繁忙的循环中轮询完成来避免这些因素。为了保证可持续的吞吐量和延迟,预发布和轮询不能被延迟,因此它们必须在独立的cpu上运行。
对于多租户系统来说,在主机CPU上轮询不是一个可行的选项,因为它必须为复制处理保留许多主机CPU。不幸的是,复制的阻塞引入了上下文切换和调度开销,延迟了网络请求处理,而来自协同运行的应用程序的干扰可能会导致调度策略和缓存影响,进一步延迟复制处理。pm优化的DFSes显示小于10 s延迟的小复制更新,加剧了任何干扰的影响。
基本原理:我们必须找到另一种方法来提供一致内容的DFS复制性能,即使在副本cpu被共同租户应用程序高度利用的情况下也是如此。同时,DFS复制不应该干扰在这些副本上共同运行的应用程序。SmartNIC可以为我们提供这两方面的好处。我们可以在SmartNIC上繁忙的轮询网络事件和处理DFS复制操作,延迟低,不干扰主机上的协同运行的应用程序。由于这些原因,LineFS卸载复制。
挑战:单纯的SmartNIC卸载(每个RDMA连接都有一个独立的轮询线程)会使SmartNIC cpu过载。它不能扩展到许多连接。同时,复制处理需要并行化,并扩展到多个SmartNIC cpu,以在SmartNIC架构上实现低延迟和高吞吐量。
方法(可伸缩,低延迟RDMA请求处理):为了实现低延迟RDMA请求处理,同时又能扩展到许多连接,NICFS将DFS请求划分为两种类型:低延迟和高吞吐量。他们使用不同的网络端口,因此LibFS根据使用情况执行不同的RPC请求。对于低延迟连接,NICFS专门为繁忙轮询提供一个线程,并固定在SmartNIC核心上。对于高吞吐量连接,NICFS维护一个在事件发生时调用的工作线程池(例如,复制确认)。NICFS使用低延迟连接来处理对延迟敏感的操作(例如,fsync()通知和租约操作),而使用高吞吐量连接来处理数据密集型操作,如复制和发布。NICFS还多路复用来自多个LineFS客户端的RDMA操作,以减少qp的数量;对于RDMA可伸缩性,有少量的qp是必要的,以避免NIC缓存抖动,并进一步减少繁忙的循环线程数。
方法(复制):为了进一步降低复制延迟,LineFS使用SmartNIC在LibFS调用fsync()之前异步地复制日志条目(以块为粒度)。在fsync()时,LineFS同步复制所有剩余的日志条目。和发布操作一样,NICFS使用流水线并行来加速异步复制。复制流水线由四个阶段组成:获取、验证、传输和确认(ACK)。回想一下,前两个阶段与发布流水线相同,为了提高效率,这两个流水线共享这些阶段。
图3显示了LineFS的复制IO路径和流水线。在主节点的NICFS中,首先获取(1)并验证(2)流水线块。然后,NICFS将块传输到下一个副本的NICFS(3)。在接收到块后,副本异步地将块复制到其本地PM日志(4),并并行地将块传输到下一个副本(4')。最后,因为最后一个副本不需要进行任何进一步的数据复制,倒数第二个副本(图3中的副本1)可以在步骤4'中直接将块传输到最后一个副本的主机PM日志,从而保存一个SmartNIC内存副本。在将流水线块复制到本地PM日志(5)之后,每个副本向主服务器发送一个ACK。这些步骤在后台主动执行,LibFS不需要被通知。
通过设计,NICFS将复制流水线并行化;例如,复制Chk1(3),同时验证Chk2(2),并并行获取Chk3(1)。类似地,复制NICFSes将每个流水线块传输到复制链中下一个SmartNICs的内存(4 ')(最后一个副本除外),并以相同的方式将块复制到它们的主机-本地PM日志(4)。复制的代价是通过将数据块重叠到下一个副本来隐藏的(图3中4和4 '同时发生)。
在fsync()上,主服务器的NICFS获取任何尚未复制的客户端私有日志条目,并使用复制流水线同步复制它们。与异步复制不同,同步复制使用低延迟RDMA连接来快速传输日志条目。完成后,主NICFS确认成功复制到LibFS(6),并且fsync()可以返回。
3.5 共享文件管理
LineFS使用租约线性化对共享状态的并发访问。租约为文件和目录提供单写入器、多读取器。LineFS遵循Assise的租约管理设计,但将租约仲裁移交给NICFS。LibFSes从SmartNIC上的NICFS租约管理器获取租约,而不是基于主机的SharedFS。与Assise一样,租约管理最初在集群管理器,然后根据LibFS请求委托给NICFS实例。一旦授予了租期,LibFS就可以访问与租期关联的文件/目录,而不需要进一步同步,直到租期到期或被撤销。只有当LibFS持有正确的文件或目录更新租约时(如在验证阶段所检查的那样),NICFS才接受已发布的日志条目。
为了提供崩溃一致性,DFS需要记录已授予的租约,这需要持久性和复制。与租约仲裁相比,复制和持久化有较高的开销,因此增加了租约操作的延迟。为了减少关键路径上的延迟,LineFS同时提供文件访问和记录租约。当授予租约时,NICFS只更新SmartNIC内存中的租期状态,然后在后台异步执行主机PM持久化和复制,而应用程序使用已授予的租期继续DFS操作。这不会影响崩溃一致性,因为NICFS会一直等待,直到调用fsync()时所有租约都被持久化和复制。
3.6 扩展NICFS可用性(x)
软件崩溃是数据中心服务器最常见的故障之一。其中,从NICFS的角度来看,最有趣的软件故障是主机操作系统的故障。此时,主机(包括主机上的DFS客户端)停止操作,不再作为DFS主节点。但是,如果主机是其他主节点的副本,那么它的服务可以完全卸载到NICFS并保持可用,即使主机已经崩溃。独立的的NICFS操作允许LineFS屏蔽主机故障转移时间,提高DFS的可用性。
为了检测主机故障,NICFS始终监视主机内核工作线程。如果NICFS检测到内核工作线程没有响应,它会认为主机关闭并切换到隔离的 NICFS操作。独立的NICFS操作继续通过PCIe上的RDMA执行复制和发布服务,在主机操作系统进行维护时保持DFS节点可用。
在独立的NICFS操作中切换是无接缝的。客户机日志和主机PM中的公共区域必须在主机操作系统崩溃时保持原位。这已经是主机崩溃后DFS恢复的要求。任何被中断的kernel worker发布操作都将由NICFS重新启动。这样做没有任何数据丢失,因为发布是幂等的。当内核worker再次可用时,NICFS可以切换出隔离操作,并向worker提交未来的复制请求。