NVM file system trends and future directions
Trends
目的
为了使内存/存储堆栈更高效,有必要合并不同的堆栈层,以减少数据复制和移动。而我们研究 NVM 的目的就在于我们想让内存/存储堆栈具有以下特点:
- 低延迟
- 高密度
- 低开销
- 高可扩展性
- 可靠性
- 耐用性
虽然目前没有一种存储技术可以提供以上全部的特性,但是 NVM 可以缩小内存与存储之间的距离。在这个观点的驱动下,人们致力于创建标准、接口、功能和编程模型等,以使操作系统、编程语言和应用程序能够有效地采用和使用 NVM。
工具和标准
-
ACPI(Advanced Configuration and Power Interface):
从6.0版本开始,加入了对 NVDIMM 的固件接口的支持。
ACPI 与 UEFI 知乎专栏 -
The JEDEC Byte Addressable Energy Backed Interface:
目的是为简化 BIOS 和 PM 的访问,具体做法是向 OS 提供了一个简化的接口。 -
Linux PMEM 驱动:
Linux PMEM 基于 BRD(Block RAM Driver),BRD 设计之初是为了支持 NVMDIMM。PMEM 在 Linux Kernel 4.1 之后加入。PMEM 使用系统保留的内存寻址范围,PMEM 允许用户模拟持久内存,因此无论内存是否是非易失内存,都可以创建并挂载文件系统。目前,PMEM 驱动程序正在更新,以支持 ACPI NFIT 的特性。
同时 PMEM 也支持把非易失内存模拟为块设备,作为块设备管理非易失内存,可以避免坏块等内存错误导致的系统崩溃等问题,同时块设备的原子性也可以得到保证。 -
DAX(Direct Access):
DAX 的思想与 XIP (eXecute In Place)十分类似,DAX 的核心思想是绕过 Linux 的 page cache,尽可能避免页面副本带来的额外开销,通过 DAX,应用软件可以直接通过 mmap 访问 PM,为了支持 DAX,文件系统和块驱动程序必须实现组成 DAX 接口的几个函数,从而允许内核执行特定的操作,比如使用页帧号分配页。
体系结构支持和一些限制
对 PM 的体系结构支持目前还存在缺失,一个例子是当前处理器的有限的物理寻址能力,对于 TB 甚至 PB 级别的 PM,显然超出了当前处理器的寻址能力,目前的处理方法是把 PM region 映射到 CPU 的物理地址空间,但是由此带来的影响目前尚不清楚:这种方式增加了 TLB 和 cache 的 miss,增加了内存归零和复制大量内存的开销,显然内存的扩展是处理器设计所需要考虑的一个重要内容。
处理器的 cache 并未针对 PM 做出优化,而目前的一些 barrier 原语以及 cache flush 操作虽然有助于 PM 的处理(个人感觉体现在数据一致性和持久性上面),但是由于其昂贵的开销导致了性能缺陷,我所理解文中的意思应该是因为这些操作大多是序列化操作,我们知道一些强序列的指令在 CPU 中是有可能让整个流水线停顿的,因此会带来很大的性能缺陷。而且当 cache line 刷新的时候,通常不保证直接接写回 NVM,关于这部分可以查看体系结构中 store buffer 等内容(不要脸的放上自己写的内容),因此 Intel 在处理器中加入了一些指令(clwb,pcommit,clflushopt等等)来保证 cache line 刷新并写回到 NVM 中。这些指令与 clflush,mfence 等指令功能上类似,不同的是这些指令不会使 cache line 失效或者使 CPU 停顿,尤其是使用 clflushopt 时尽可能保证指令流水线执行,我这里理解应该是尽可能减少了有序性以支持乱序。pcommit 指令的目标是确保内存控制器接受的写操作被同步地提交到持久内存中,但是,因为所有即将到来的内存控制程序都已经有硬件机制来执行这一点,所以该指令逐步被弃用。
处理器对 PM 的支持还包括内存保护键(memory protection keys),新增了一个32位寄存器,定义了16组2位的页权限(读写),MPK 支持对 mprotect 的高效实现,保护内存免受 stray writes 污染、避免了 TLB 的刷新且不影响性能。TLB 对地址转换的影响十分重要,进而对整个系统的性能表现举足轻重,虽然不是一个新话题,但是大容量存储以及NVM 文件系统的出现,为这个问题引入了一个全新的视角(什么新的视角文中也没说...)。
编程模型
传统的访问接口和编程模型并不能完全发挥 NVM 的潜力,因此很多研究着眼于创造新的编程模型,存储和网络行业协会(SNIA)已经定义并发布了 NVM 编程模型(NPM)规范,为开发人员提供了一些提供通用和可扩展 PM 访问模型的指导。NPM 定义了许多访问模式,同时 NPM 提供了一些详细信息来帮助发现被一些特定实现支持的操作,最后 NPM 提供了一些例子介绍一些操作的用法以及一些例程。
NVML 是一个开源库,目的是对 PM 提供简单高效的访问,NVML 提供 NPM 中指定的设计原则,添加了一些指定特性,使内存开发更加直观。它拥有处理不同抽象(如对象、文件、附加日志和块)的工具。它还向用户公开底层功能,如 cache flushing 和优化的文件映射。在更高级别的库中,NVML支持原子事务、持久指针和列表,以及多线程的同步。最后,NVML 还提供了一个 c++ 版本的API,允许在PM之上进行更直观、更健壮的面向对象编程。
Future Directions
上图展示了不同的 NVM 解决方案分别解决的问题,以及这个问题的研究程度,研究程度分为高中低三个档次,高表示这个问题已经被相对充分研究,并有公认的优秀解决方案;中表示这个问题虽然已被广泛研究,但是并无一个公认的解决方案,还需要进一步探究;低表示这个问题并未得到充分关注,并很有潜力成为新的研究热点。
而没提到的一些问题,比如空间效率、能源效率、垃圾收集、碎片、持久缓存、并行性和挂载时间等等也同样重要,但是因为目前这些问题暂时不会直接影响 CPU 访问 NVM,所以在近一段时间内,这些问题并不会成为研究的热点。
必须指出的是,针对众多不同的体系结构总结他们的 NVM 存储结构是十分困难的,所以文章只针对下图这种通过内存总线访问 NVM 的体系结构,这种体系结构下,CPU 可以通过总线直接访问 NVM,在性能上是一个不错的选择,但是,相应的会带来 cache reordering 和 stray writes 持久化的问题。
高
-
Consistency Guarantee
代表方法:细粒度日志(fine-grained journaling)、log-structured 文件系统以及短路影子页(short-circuit shadow paging)更新等等。现有的一致性保证机制大多是从传统的机制上改良而来。同时,一致性会随着文件系统以及元数据管理的发展而发展,所以并不代表目前的一致性保证方案就是完美的,但是目前看来,现有的一致性保证机制可以比较好地完成 NVM 存储中的已执行任务。 -
Atomicity
代表方法:原子映射(atomic mapping),轻量级事务(lightweight transaction)等。与一致性保证类似,原子操作和事务的研究以及解决方案也多为传统方法的改良。在 PMFS 的精读笔记中有提到,文件系统中数据一致性与原子性是高度相关的,因此,数据原子性的发展与一致性的发展相似,都是完成度比较高的。原子性问题同时也与一些其他问题,比如 cache flush 的有序性问题相关,虽然原子性问题还有很高的研究空间,但是现有的解决方案可以较好地满足要求。 -
Endurance
目前 NVM 的一些产品作为存储层次,已经达到了应用的水平,同时 NVM 与 DRAM 和 SRAM 的组合应用有效地避免了 NVM 耐久性的问题,虽然目前 NVM 技术本身仍然有耐久性的限制,但是可以通过磨损均衡以及其他的技术从文件系统的实现中解耦出来,举例来说,在内存管理部分实现磨损均衡等技术,或者采用其他特定的硬件(必要时将逻辑地址空间重映射到物理地址空间,这类似于SSD中的FTL支持的解决方法)等等。 -
Software Overhead
传统的文件系统通过减少 IO 调度层或者不使用 page cache 减少软件层面的额外开销。现有的机制,例如 XIP,通过绕过 cache 过程直接将 page 映射到用户空间会带来性能提升。同时,通过避免底层操作(比如进入内核)、减少使用内存映射切换操作级别、执行同步操作而不是使用中断都可以对软件开销进行微调。
随着访问 PM 的关键路径转移到更低层次,以及代码变得更难优化,识别以及消除软件开销变得更加困难。随着诸如一致性、块分配和损耗均衡算法等昂贵的机制不断发展并变得更加复杂,预计 PM 对文件系统开销将不再那么苛刻。在内核方面,与内存相关的机制,特别是在访问数据过程中起主要作用的地址转换过程的未来是不确定的。与元数据类似,随着 PM 存储寻址机制的转变,文件地址空间也会与 OS 以及进程内存空间混合在一起。因此对软件额外开销的优化更加困难,并且相比于寻址问题,额外开销目前显得并不是十分重要。 -
Reliability
现有的方法包括:检查点算法和 RAID-like,这些方法都已经得到广泛应用。虽然也需要对 NVM 更加友好的算法,但是这并不是一个很苛刻的领域,目前还是更关注轻量的一致性机制以及元数据一致性机制。由于目前 NVM 中的数据冗余还并没有相关的研究,这个方向未来有可能会发展成更复杂的一致性机制,至少从现在来说,可靠性这个问题还并不是那么重要。 -
Access Transparency
确保技术的兼容性不应该是文件系统关注的问题之一,但是对于应用程序来说,依赖 NVM 文件系统来实现一致的行为是很重要的。但是目前最需要的是如何把应用程序的数据暴露出来,使得数据与处理器之间的距离缩短,而访问透明在 NVM 产品逐步进入市场时也是十分重要的,因为市场可能会更倾向于选择做出尽可能少的改变就可以使用的技术。 -
Data Duplication
在文件系统与主存混合的架构下,数据副本的数量自然会减少,因为很多的传统存储结构中的缓冲区、缓存和软件层都不复存在。因为 CPU 可以直接访问应用数据,避免了页交换以及 page cache 的使用,此外,允许页面直接映射到用户空间的 DAX 机制(比如 XIP 等)是一种几乎不涉及数据复制的解决方案。因此目前最先进的 PM 文件系统已经达到了对 PM 页面的零拷贝访问。例外的情况是诸如异地更新等等必须拷贝数据的情况,对于这些情况,必须要考虑内存占用和可靠性之间的折中。
中
-
Access Interface
虽然现在许多 PM 文件系统对 POSIX 接口(read,write,mmap等)都有实现,但是并不是访问 PM 设备最适合的方法。目前操作系统优化以及应用程序级的指令逐步在利用 PM 的特性,但是并没有一个公认优秀的框架。目前的许多解决方案都是基于当今的编程模型和模式,因此随着编程模型的发展和对支持 PM 环境的逐步采用,存储接口和访问方法也必须随之发展。
因此,重新审视和评估文件系统在体系结构中扮演的角色就变得至关重要,NVM 的出现使得内存和存储之间的界限变得越发模糊,这也意味着一些之前不可行的数据管理方式在 NVM 的支持下或许将变得可能。这些都表明访问接口或许是与 NVM 文件系统相关的研究中较为重要的一个方向,同时,对访问接口的研究并不局限于文件系统,这对整个 NVM 支持的系统软件都是一个潜力巨大的方向。 -
Asymmetric Latency
这里的不对称延迟主要指的是针对 NVM 的 write/earse 操作与 read 操作之间延迟的不对称。对于这一特性,OS 并没有太好的解决办法,目前的解决方法是尽可能减少写放大,或者使用尽可能快的 buffer 来缓存文件,那么假设 NVM 设备并不会提升写操作的性能表现,那么研究的目的是至少使其与 DRAM 等易失存储的写操作性能表现相当,而最主要的因素在于影响 NVM 写操作性能的因素有很多,它们之间的联系与区别目前也不甚明了,所以分析并指出影响写操作性能的因素也是一个至关重要的方向。 -
Block/Page Allocation
块分配算法有很多,但是目前仍存在一些问题。现有的块分配算法的设计目的是减少碎片来提高 NVM 的寿命,在块分配过程中进行这些操作很有可能是多余的,但是作为文件系统的核心概念,在处理文件系统并发或者地址翻译时,块分配策略必须要被优化,而现在的优化策略十分复杂而且对整个系统的影响也不清晰。今后的块分配算法需要轻量、高并发并且灵活。 -
Cache Optimization
传统的 cache 和 buffer 的优化主要针对于 SSD 设备,因此并不能应用于 PM 文件系统。目前主要的研究方向在于试图有效加强 cache 和 PM 之间的一致性,另一个具有研究潜力的是对 TLB 的改进。因为 TLB 主要涉及地址翻译,地址翻译与内存保护依旧是文件系统中十分重要的研究方向。同时,针对 TLB 的改进对整个文件系统产生的影响尚不清楚,在以后的研究中需要进行深入的分析。 -
Write Amplification
通过减少数据副本,优化日志结构,以及有效地垃圾回收机制,NVM 在一定程度上已经减轻了传统文件系统中出现的写放大问题。此外随着应用程序逐渐被允许直接访问持久内存,OS 与文件系统之间的交互会越来越少,那么写放大自然也会变少。细粒度日志、原子原地更新,直接映射等技术的利用有效地减少了写放大,虽然从性能和能耗角度来看,最小化写放大现象十分重要,但是随着文件系统变得更加灵活,操作变得更加细粒度,写放大的性能开销或许也是可以接受的。
低
-
Metadata Management
PM 的引入会带来许多问题,包括是文件系统是分层结构更好还是平面组织结构更好,更根本的是对于一个基于内存的存储系统来说,文件到底是不是一个最好的数据抽象方式。关于元数据管理的研究有很多,但是大多是基于 SSD 的,而且也没有解决上述提出的问题。
传统的元数据结构是针对块设备文件系统设计的,对于 SSD 可能适用,但是对于 PM 能否良好的适配是一个疑问。所以元数据管理,与访问接口一样,都是 NVM 研究中非常具有潜力的方向,而且有可能从根本上改变内存数据的抽象结构(这也太难了。。。),虽然目前并不存在一个元数据应该怎样管理的泛式,但是,文中认同使用更小的元数据结构,着眼于更细粒度的操作以及尽可能减少应用与数据之间的交互。元数据因此可能与 OS 和应用内存结构混合从而使得持久数据与应用数据更近,提供更多更灵活的数据操作方式。 -
Memory Protection
内存保护在 NVM 出现的今天出现了全新的应用场景和需求。现有的趋势是通过设置页表条目和寄存器保护位的开关控制 PM 内存页的写权限(例如 PMFS 和内存保护键 MPK 等)。然而,这些方法似乎并不是问题的有效解决方案,一些方法可能会带来巨大的开销,其他方法则依赖于硬件创新和一些实验方法。内存保护的地位十分重要,根本的解决思路是重新审视 OS 与文件系统层次的寻址结构以及它们之间的交互方式。 -
Cache Consistency
理想情况下,处理器的 cache 应该是持久的,来避免 NVM 存储与易失的 cache 交互。但是由于 NVM 的属性限制,现在并不存在持久 cache。现有的处理方法是使用处理器指令将数据从易失性内存有序的刷到 NVM 来保证 cache 的一致性,同时优化 cache 和处理器来减轻这样的影响,这样做看起来合理,但是结果上看来并非如此。有研究表明,使用 memory fence and flush 的 cache 写回模式的性能比单纯的写直达性能差两倍,在某些情境下,甚至不如不使用 cache 的性能。因为目前处理器缺乏对上述 cache 机制(memory fence and flush)的支持,必须要理清易失性 cache 和 NVM 之间的联系与区别,现有的方向是提供更稳定和透明的 cache 管理,比如 epoch barriers 等机制。 -
Data Placement
在本文所关注的体系结构中,采用块放置策略有助于高效地使用多个内存层或者混合内存(DRAM and PM)。虽然不需要在两种内存之间进行数据复制,但是使用更快速的内存(比如 DRAM)缓存常用的数据(metadata等)还是一个有趣的问题。目前对于本文关注的这种混合内存结构的块放置技术的研究还是不多,对此产生的影响也比较匮乏。
说到数据放置,可能最直接的想法是冷热数据分离,但是这需要 NVM 与应用程序之间进行交互分析,这是个艰巨的任务,所以数据放置也是 NVM 文件系统中的一个重要研究方向。 -
Scalability
目前对于内存总线上大量 PM 对整个体系结构产生的影响还没有很多的研究,因为 PM 实际上使用了内存管理资源,比如内存控制器,TLB 等翻译机制,同时,VFS 的设计实际上是对 cache 和 TLB 低效的,因为保证通用性的同时就会做出一定的折中,目前由于实验环境的限制,PB 级别的 PM 会怎样影响内存管理资源还不清楚。
目前,可扩展性的研究很少,可扩展性研究对构建巨大内存结构的意义无疑是重大的,虽然可扩展性的内存结构会变得更复杂,难以设计,但是未来一定会受到更多的关注。
总结
虽然 NVM 在大规模商用上面还存在限制,但是随着 NVM 的发展,文件系统与内存管理之间的界限正在变得模糊,因此,当持久数据(文件,对象,地址空间等等)集成到 OS 中管理和访问时,传统的易失结构与持久结构就会变得混淆,此外,在 NVM 中将数据建模为内存结构与将其建模为传统文件之间似乎存在冲突。使用内存驱动的方法可以避免将序列化数据从编程和内存友好的模型转化为更传统的文件或数据库格式。然而这意味着对传统文件系统的改变。
尽管这些解决方案还处于早期阶段,但还是有可能发现一些有趣的趋势,比如直接映射 NVM regions (XIP 或DAX 概念)或使用用户级文件系统来减少进入内核的开销。虽然NVM芯片本身在市场上还没有广泛使用,主要是通过调整传统访问接口(第一步),但是在工业和学术界,已经有大量的研究和开发项目符合第二个甚至第三个步骤中所描述的部分即为我们演示了我们的结果,已致力于 NVM-improved 存储系统,如文件系统的设计和基于对象的存储库,另外,进程空间中的持久化内存映射和正交持久化等机制也是很有趣的方向。
个人总结
个人感觉可以进一步研究的方向:
- Access Interface
- 简易的 metadata management(tree结构等等)
- Asymmetric Latency
- Data placement
- Memory Protection
研究程度是高的这些方面都需要在文件系统中有所体现。
参考资料
Puglia, G. O., Zorzo, A. F., De Rose, C. A. F., Perez, T., & Milojicic, D. (2019). Non-volatile memory file systems: A survey. IEEE Access, 7, 25836–25871. https://doi.org/10.1109/ACCESS.2019.2899463