日志文件系统的设计与实现

来源:互联网 发布:金汇宝软件 编辑:程序博客网 时间:2024/06/05 01:52

from The Design and Implementation of a Log-Structured File System——–Mendel Rosenblum and John K. Ousterhout

摘要

这篇文章提出了一种叫做日志式文件系统的新的磁盘管理技术。日志式文件系统将所有的更改以日志式的结构连续的写入磁盘,以这种方式来同时加速了文件写入和崩溃恢复。日志是磁盘的上唯一的结构,它包含了查询信息,通过它文件就可以从日志中有效的读回来。为了在磁盘中为快速的写文件保留保留大块的空闲区域,我们将日志分成segments, 并且使用segment cleaner从严重分片的segments中压缩有效数据。我们提出了一些仿真来演示一个简单清理策略的效率,这种策略基于开销和动作。我们实现了一种叫做Sprite LFS的原型日志式文件系统,它在写大量小文件方面超越了当前的Unix 文件系统,并且能够达和并超越Unix在读和大文件写方面的效率。尽管清理的总开销也算在里边,Sprite LFS 文件系统写操作能够使用磁盘70%的带宽,传统的Unix 文件系统只使用了5~10%。

1. 介绍

在过去的10年间,CPU的速率在飞速的增长,而磁盘的访问速度却增长的很慢。在未来这种趋势还将继续下去,这将导致越来越多的应用成为受磁盘限制的应用。为了减轻这种影响,我们提出了一种叫做日志式文件系统的磁盘管理技术,日志式文件系统一种比当前文件系统更有效的方式使用磁盘。
日志式文件系统基于这种假设:文件被缓存在内存当中。当缓存的越来越多时,cache就会比较有效的满足读请求。结果就是,与磁盘的交互就主要受限于写操作。日志式文件系统将所有的新信息以一种叫做log的连续的结构写入磁盘。由于这种方式取消了几乎所有的寻道操作,因此极大的提高了写操作效率。log结构这种连续的属性也允许更快的崩溃恢复。当前的Unix文件系统在崩溃后通常必须扫描整个磁盘来恢复,但是日志式文件系统仅仅需要检测日志的最近的部分。
日志并不是一个新概念,有很多最近的文件系统已经将日志作为一种附加的结构来加速写操作和崩溃恢复。然而,这些系统仅仅是用日志来最为暂时的存储,数据永久存储的位置还是磁盘上的随机访问的存储结构。相反,日志式文件系统将数据永久的存储在日志当中,并且磁盘上不会有其他的结构。日志有查询信息,这样相比于现在的文件系统,文件可以被有效的读回来。
对于可以高效工作的日志式文件系统来说,它必须保证总是有大块的空闲空间用来提供给写数据操作。这是设计日志式文件系统的最困难的挑战。在这篇文章中我们提出了一种基于叫做segments的大范围区域,会有一个持续工作的segments cleaner 进程通过从严重分片的segments 压缩有效数据来产生空闲的segments。我们用一个仿真器来研究不同清理策略,并且发现了一种基于开销和动作的简单但是高效的算法。它将老的、更新频率低的数据与经常更新的数据分离开来,在清理的时候做不同的处理。
我们已经构建了一种日志式文件系统的原型,它叫做Sprite LFS, 是 Sprite 网络操作系统的一部分。平台程序演示了Sprite LFS的小文件原始写速度比Unix 高出了一个数量级。对于其他的负载,比如读操作和大文件访问,Sprite LFS除了在一种测试用例(在文件随机写后再连续读),在其他的测试用例上都至少与Unix有相同的效率。我们也在系统中测量了清理的长期负载。总的来说,Sprite LFS 允许65~75%的磁盘带宽用来写数据,剩下的用来清理数据。而Unix系统仅仅只利用了5~10%的带宽用来写数据,剩下的时间用来寻道。
这篇文章剩下的部分分成6个小节。第二小节回顾了90年代设计计算机文件系统所存在的问题。第三小节讨论了源自Sprite LFS的日志式文件系统的设计备选方案,并在这里特别说明清理机制。第四小节描述了Sprite LFS的崩溃恢复机制。第五小节用测试程序测试了Sprite LFS,并长时间测试了清理工作的开销。第六小节将Sprite LFS 与其他文件系统进行了比较,第七小节进行了总结。

2. 90年代文件系统的设计

文件系统的设计由两个因素决定:技术和工作负载。技术提供了基本的构建单元(block)。工作负载决定了必须有效执行的一组操作。这个小节总结了当前的技术改变和它对文件系统设计的影响。而且也描述了影响Sprite LFS的工作负载因素,并且展示了当前文件系统在处理技术改变和工作负载问题上不足。

2.1 技术

有三个技术单元对文件系统设计有着决定性的影响。它们是处理器,磁盘和内存。处理器是影响巨大的因为它们的速度是成指数级别增长的。并且它的增长在90年代还将继续下去。这就在对计算机系统的其他组件的提速产生了压力,因此这个系统是不平衡的。
磁盘技术也提高的很快,但是这种提高主要集中在成本和容量上,而不是在性能上。在磁盘性能方面有连个评价指标:传输带宽和访问时间。虽然这两个因素都在提高,但是增长速度比CPU增长速度慢多了。磁盘传输带宽通过使用磁盘阵列和并行磁盘能够得到显著的提高,但是没有有效的方式来提高访问时间(这是由磁盘机械结构决定的)。如果软件发起了连续的对于寻道分离的小数据量传输,那么这个软件再下一个十年用更快的处理器也不会加速很多。
第三的技术单元是内存,它在容量上以指数级别增长。现代文件系统都是将最近使用的数据cache到内存中,更大的内存能cache更多的数据。这里有影响到文件系统的连个因素。第一,更大的文件缓冲区会吸收掉大部分的读请求,这样会改变对磁盘施加的负载状态。大多数的写请求在安全性上就会被影响,所以磁盘数据交换将会更多受制于写操作。
第二个大文件缓存的影响是,它们可以作为写buffer,那么大量的block修改就能在将其写入到磁盘之前收集起来。Buffer能够使得磁盘的写入更有效,例如将数据写入到只需要一次寻道的连续传输当中。当然写缓冲的不足就是在崩溃的时候,会增加丢失数据的数量。在本文中我们假设崩溃不是经常发生,并且每次崩溃只会丢失几秒钟或几分钟的工作数据。那么对于那些需要更好的恢复性能的应用程序来说,写buffer需要使用非易失性的RAM。

2.2 工作负载

在计算机应用软件中有若干种不同的文件系统负载。其中文件系统设计中需要有效处理的一种最困难的工作负载存在于办公和工程环境当中。办公和工程软件会经常性的访问小文件。有些研究测量了这类软件访问的平均文件大小为几KB。小文件会导致小的随机磁盘IO。并且对这些文件的创建和删除要通过修改文件系统的元数据(metadata: 用来定位文件属性和文件存储block的数据结构)来完成。
在超级计算机环境当中连续访问大文件的工作负载也是一种感兴趣的问题,但是这并不是对于文件系统的。很多已经存在的技术用来保证这样的文件在磁盘上是连续存储的,因此,IO performance 主要受限于IO 带宽和内存子系统,而不是文件分配策略。在设计日志式文件系统中,我们决定集中在小文件的有效访问上,将提高大文件访问带宽留给硬件设计者。很幸运的是Sprite LFS 中用到的技术对于大文件也运行的很好。

2.3 当前文件系统存在的问题

当前文件系统主要存在两个问题,这两个问题使得处理90年代的技术和负载变得非常困难。第一,它们将管理信息散布在整个磁盘当中,使得产生了大量的小单元访问。例如,伯克利Unix FFS能有效处理连续存储在磁盘中的文件,但是它物理上分离了不同的文件。更多的,文件的inode是与文件的内容分离的,存储文件名的目录问价也是这样。这需要至少5次分离的磁盘IO, 每一次都要先进行一次寻道,才能在Unix FFS中创建一个新文件。五次IO包括两次对文件属性的不同的访问,加上访问文件数据的一次、目录数据的一次、目录属性的一次。当在这样的系统中写小文件时,低于5%的磁盘有效带宽被用来处理新数据,剩下的时间都消耗在寻道上面。
当前文件系统的第二个问题是:它们都倾向于同步写入,软件必须等待写完,而不是当写入在后台执行时,程序继续运行。例如,尽管Unix FFS 是异步写入文件数据的,文件系统元数据结构例如目录和inode是同步写入的。对于许多小文件的工作负载,磁盘数据流主要由元数据同步写入决定。同步写影响了软件与磁盘交互的表现,使得软件很难从更快的CPU中获得更好的表现。它们也将写入失败的文件文件CACHE作为写入缓冲区。不幸的是,像NFS这种网络文件系统引进了一种不应该再存在的同步操作。这样虽然简化了崩溃恢复,但是它降低了写的performance。
虽然这篇文章用berkeley Unix FFS 作为当前文件系统的一个例子,并且拿他与日志式文件系统来比较。Unix FFS 的设计仍然在使用,因为他有很好的文档记录,并且在很多Unix操作系统都在使用。这节中提出的问题不是只在Unix FFS中存在,在很多其他文件系统中都可以找到。

3. 日志式文件系统

日志式文件系统的基本思想是通过将连续的文件更改缓存在文件cache中,然后在一次写操作中将所有的更改连续的写入。在写操作中写入磁盘的信息包括文件数据块,属性,序号数据块,目录以及所有的用来管理文件系统的信息。对于小文件写负载,日志式文件系统将传统文件系统中大量的小的同步随机写操作转换为大块的异步连续传输,这样能够利用磁盘接近100%的原始带宽。
虽然日志式文件系统的基本思想是简单的,为了可以实现日志方式的优势,有两个关键问题需要解决。第一个是如何从日志中获取信息;这是3.1节的主题. 第二个问题是如何管理磁盘中的空闲空间,使得在向磁盘中写入数据时总是有大块的空闲空间可以使用。这是一个十分困难的问题。这是3.2~3.6小节的主题。表1列出了Sprite LFS用来解决上述问题所使用的磁盘数据结构。这些数据结构会在后边详细说明。

这里写图片描述

3.1 文件的定位和读

虽然日志式这个词语表示顺序扫描才能从日志中获取信息,但是在Sprite LFS中并不需要这么做。我们的目标是达到并超过一般Unix文件系统的读效率。为了达到这个目标,Sprite LFS将index结构输出到日志中,来允许随机获取。Sprite LFS使用的基本结构跟Unix 文件系统使用的结构相同。对于每一个文件都对应有一个用来保存文件属性信息和文件前10个block磁盘地址的inode结构。对于文件大小超过10个block的文件,inode中包含这些block的间接block,每一个block中数据的地址和更多的间接block。只要找到文件的inode结构,读文件需要的磁盘IO在Sprite LFS 中和在普通Unix 文件系统是相同的。
在Unix 文件系统中inode位于磁盘的固定位置。
给出文件的识别号,进行简单的运算就可以得到文件inode的磁盘地址。相反的是Sprite LFS 并不把inode放在固定的位置,它们放置在log中。Sprite LFS使用一个叫做inode map来维护每一个inode的当前位置。给出文文件的识别号,inode map必须可以相应的inode。inode map被分成block写入日志当中。磁盘中有一个有固定位置的检查点区域识别所有inode map block的位置。幸运的是,inode map很紧凑,很容易缓存在内存当中,并且inode map的查询几乎不需要访问磁盘。
图1展示了Sprite LFS和Unix 文件系统在不同目录下创建了两个新文件后的磁盘层次结构。虽然两层有相同的逻辑结构,但是日志式文件系统提供了一种更紧凑的方式。因此Sprite LFS 在写效率上比普通Unix文件系统要好很多,在读取效率上也很好。
这里写图片描述

阅读全文
0 0