这是一篇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中直接写入。
网友评论