美文网首页HPC专题
《A High Performance File System

《A High Performance File System

作者: CPinging | 来源:发表于2019-10-07 10:19 被阅读0次

    这是一篇Eurosys 16的清华文章,我将其做一个简单的总结工作

    Introduction

    由于:Given the anticipated high performance characteristics of
    emerging NVMMs, recent research [6, 13, 18, 49] shows that the overheads from the generic block layer and copying data between the OS page cache and the NVMM storage significantly degrade the system performance.

    文中讲到许多方案将通用IO层拿掉,以用来提升效率。

    但是这样会由于NVM的读写不对称问题而导致性能下降。所以不得不对写操作进行buffer。好处有一下两点:

    • writes to the same block may be coalesced since many I/O workloads have access locality【可以整合这一个阶段中对同一个块的IO,以便减少操作次数】

    • writes to files that are later delet- ed do not need to be performed.【如果数据在这个阶段被删除的话,可以避免写入】

    那怎么解决持久化问题呢(需要做trade off)?

    问题反复提到了两次复制的问题。(将数据复制到DRAM的cache中;使用fsync将数据复制到存储中)

    文章点明了目的:The goal of HiNFS is to hide the long write latency of NVM- M whenever possible but without incurring extra overheads, such as the double-copy or software stack overheads, there- by improving the system performance

    即:降低NVM写延迟并且不带来额外的开销。

    HiNFS使用DRAM做NVM的cache,并且使用memory的接口来代替速度慢的通用层。

    上述情况为lazily,而对于eager-persistent file writes我们需要直接操作。但是这又引起了一致性的问题。所以需要系统能够检测到写的具体模式并作出相应的操作。

    这里提到了HiNFS主要是针对文件IO进行的优化,而对MMap IO也有支持。

    image.png

    这个图中能够看出有一些应用是需要fsync的,而fsync的比例高说明

    Memory mapped I/O就是把磁盘上的file映射到内存上,当我们从内存上fetch byte时,对应的file就被读取。同样的,当我们在内存上存储字节的时候,对应的file就被写入。这就让我们不需通过read和write系统调用而去操作I/O。mmap内存映射建立一段可以被多个进程读写的内存段。共享内存。

    要坚信文档中说的,read和write是肯定有缓存的,这是内核为了提高硬盘效率必须做的优化。而为什么楼主测试的程序会看不出效果呢?原因其实你已经知道了,因为缓存是对内核而言,不是对程序而言的,所以内核存在一定的同步机制,不会让这种情况发生,具体是怎么同步的呢,大概是这样的,执行write之后,内核将数据缓存起来,等到缓存区满了之后或者执行了fsync再强制写入硬盘,这时候其实数据还不一定到了磁盘,因为硬盘也有一个缓存区,数据会首先写入那里。但是如果这是执行了read尝试读取刚刚写入的数据,内核会先判断这段数据在在缓存中有没有更新,如果有就会直接从缓存读取,所以就会产生一种假象,数据已经被写入硬盘,这其实是内核的一种策略。如果你想看数据是不是真的被写入硬盘,很简单,执行write之后,直接拔电源,重启后看看数据文件中数据是不是更新了。要强调一点,内核何时把数据写入硬盘是不确定的,所以即使拔电源也不一定会看到数据没有更新,但没有更新的概率会很大。

    这里插入一些相关解释:

    write

    ssize_t write(int fd, const void *buf, size_t count);

    将数据写到文件中. 注意, 如果文件是保存在硬盘中, write() 函数调用返回之后, 并不表示数据已经写入到硬盘中, 这时如果掉电, 数据可能会丢失.

    fsync

    int fsync(int fd);

    程序调用本函数, 通知内核把数据写到硬盘(file)中. 比如, 你开发一个数据库软件, 就需要这样的函数, 否则掉电或者系统崩溃时便会丢失数据.

    如果你的程序不调用 fsync(), Linux 内核也会自动在”合适”的时候将你的数据真正写入到硬盘(类似调用 fsync), 最长的延时默认是 30 秒.

    这里有一个小疑问:

    simply using DRAM as a cache of NVMM may improve the performance for workloads having many lazy-persistent writes, but this simple design will significantly degrade the system performance for workloads containing many eager- persistent writes due to the double-copy overheads

    为什么这里说到用DRAM做cache是可以提高那些lazy-persistent密集型应用,但是对于eager- persistent 应用却不太好。

    我认为是不是这样:eager类型的写本来就需要实时性,所以将其先保存到DRAM中还是要立刻刷到NVMM中,所以是多此一举的。而利用Buffer的概念是为了有个时间差,但是这种模式不需要时间差,所以不合适。

    HiNFS设计

    image.png

    上面的模式为传统的模式,需要两次复制(块设备与OS page;PS page与user的buffer)。这个花销太大。

    image.png

    上图为NVM-aware的文件系统,该系统仅需要一次用户buffer到NVMM的复制。

    但是这个没有考虑NVMM的写问题。所以提出了第三种设想:

    image.png
    • HiNFS使用buffer对lazy-persistent操作。并用细粒度的buffer管理。

    • 降低两次复制带来的开销。(buffer降低了写延迟但是同样带来了两次复制的问题)

    NVMM-aware Write Buffer Policy To

    image.png

    先判断是不是lazy,如果是直接放到DRAM的buffer中。用以进行IO整合工作以便提高性能。

    image.png

    上图为DRAM Block Index in HiNFS。

    树的索引中,key表示了DRAM中块的逻辑文件偏移量;而value表示DRAM物理块号对应的NVMM中的物理块号。并可以后台将DRAM块刷到对应的NVMM块地址中。

    为了保证数据一致性,HiNFS使用了多线程将DRAM中的块刷到NVMM中。并且有两个唤醒条件。

    而这里需要注意的是:传统buffer管理方案使用的粗粒度的,而这里需要用细粒度的。

    这里仍然存在两个问题:

    • Dram中没有空间了,那就要等待

    • 空间不足的时候lazy与eager要竞争那些空间

    为了解决问题,这里提出了Cacheline Level Fetch/Writeback (CLFW)

    用其来追踪DRAM块中的cacheline的状态。当DRAM中的块数据需要转移到NVMM的时候,那么我们需要检查该其标志是否为1 。

    这里放一个cache line的解释:https://blog.csdn.net/qq_21125183/article/details/80590934

    文中提到了一个fetch-before-write不是很懂??

    Elimination of the Double-Copy Overheads

    文中说道其发现了两个造成double-write的原因。

    读是非常简单的,应为dram与nvm读速度相当,所以可以直接读取即可。

    然而,在读的过程中为了找到最新的数据,首先查找DRAM Block Index是在dram还是在nvmm。

    在nvmm中直接读,在dram中在去找Cacheline Bitmap。

    上面是读操作,下面是eager写操作。

    直接写到nvmm中即可。

    • 同步写:调用sync操作。

    • 异步写:异步写入,同步操作。在sync调用前整合了一批异步写,此时将写入操作整合,类似于lazy写。所以发现写类型十分重要。

    所以设计了Buffer Benefit
    Model,来检测是否有足够的异步写。使用了最近的系统异步写历史信息来帮助我们进行判断。并且每4kb数据设置了一个Eager-Persistent位,来判断写入的类型。

    文中也具体引入了一个公式来对该表标记位进行设置。

    开始的数据均标记为lazy,并在之后动态调整。

    为了预测下一个到来的写操作是什么类型的,本文引入了一个公式来预测。结果如下:

    image.png

    效果很棒。
    These results demonstrate that the synchronization information of a block remains nearly the same within a short time period

    为了保证NVM与DRAM中的数据一致性,如果为同步写情况,那么我们进一步检查buffer是否在DRAM中;如果在NVM中直接写入。

    相关文章

      网友评论

        本文标题:《A High Performance File System

        本文链接:https://www.haomeiwen.com/subject/looupctx.html