分享

【F2FS】文件系统设计背景与功能

 平淡水的平凡 2017-03-29

 

来源:chinaunix

作者:登高望远海


1、F2FS文件系统简介

F2FS (Flash Friendly File System) 是专门为基于 NAND 的存储设备设计的新型开源 flash 文件系统。特别针对NAND 闪存存储介质做了友好设计。F2FS 201212月进入Linux 3.8 内核。目前,F2FS仅支持Linux操作系统。

F2FS 选择 log-structured文件系统方案,并使之更加适应新的存储介质(NAND)。同时,修复了旧式日志结构文件系统的一些已知问题,如(1) wandering tree 的滚雪球效应和(2)高清理开销。

根据内部几何结构和闪存管理机制(FTL),闪存存储设备有很多不同的属性,所以F2FS的设计者增加了多种参数,不仅用于配置磁盘布局,还可以选择分配和清理算法,优化性能(并行IO提高性能)

1.1 F2FS文件系统的设计背景和要解决的主要问题

1.1.1 LFSLog-strctured File System

为管理磁盘上的大的连续的空间以便快速写入数据,将 log 切分成 Segments,使用 Segment Cleaner 从重度碎片化的 Segment 中转移出有效的信息,然后将该 Segment 清理干净用于后续写入数据。

1.1.2 Wandering Tree 问题

 LFS 中,当文件的数据块被更新的时候是写到 log 的末尾,该数据块的直接指针也因为数据位置的改变而更改,然后间接指针块也因为直接指针块的更新而更新。按照这种方式,上层的索引结构,如 inodeinode map 以及 checkpoint block 也会递归地更新。这就是所谓的 wandering tree 问题。为了提高性能,数据块更新的时候应该尽可能地消除或减少wandering tree 的更新节点传播。

1.1.3 Cleaning 开销

为了产生新的 log 空闲空间,LFS 需要回收无效的数据块,释放出空闲空间,这一过程称为 Cleaning 过程。Cleaning 过程包含如下操作:

(1)通过查找 segment 使用情况链表,选择一个 segment

(2)通过 segment summary block 识别出选中的 segment 中的所有数据块的父索引结构并载入到内存;

(3)检查数据及其父索引结构的交叉引用;

(4)选择有效数据进行转移有效数据。

Cleaning工作可能会引起难以预料的长延时,因而 LFS 要解决的一个重要问题是对用户隐藏这种延时,并且应当减少需要转移的数据的总量以及快速转移数据。

2、F2FS文件系统特性和功能

2.1 F2FS不支持的特性和功能(后续可能会支持)

当前F2FS不支持如下的特性,但是这些特性在以后如果必要的话也会支持:

(1)快照

(2)用户配额——最难实现

(3)不支持NFS

(4)不支持“security”方面的扩展特性(xattrs)

2.2 F2FS的特性和功能

F2FS具有以下特性和功能:

(1)最大文件系统16TB

(2)32位块寻址空间;

(3)最大文件大小3.94TB

(4)Log-structured

(5)Flash 感知

a) 扩大随机写区域(元数据区域,two-location)以获取更好的性能;

b) 尽量使 F2FS 的数据结构与 FTL 的运算部件对齐。

(6)解决Wandering Tree 问题

a) 用术语“node”表示 inode 以及各种索引指针块;

b) 引入 Node Address Table (NAT) 包含所有“node”块的位置,这将切断数据块更新的递归传播。

(7)最小化Cleaning 开销

a) 支持后台 Cleaning 进程;

b) 支持 greedy 和 低成本(转移数据最少)的待清理 Section 选择算法;

c) 支持 multi-head logs 用于动态/静态 hot  cold 数据分离;

d) 引入自适应 logging 用于有效块分配。

3、F2FS文件系统的磁盘布局分析

F2FS 将整个卷切分成大量的 Segments,每个 Segment 的大小是固定的2 MB。连续的若干个Segments 构成 Section,连续的若干个 Sections 构成 Zone。默认情况下一个 Zone大的大小是一个 Section,而一个 Section 的大小是一个 Segment

F2FS 将整个卷切分成6个区域,除了超级块(SuperblockSB)外,其余每个区域都包含多个 Segments

 

3.1 块(Blocks)、段(Segments)、区段(Sections)、存储区(Zone

3.1.1 Blocks

(1) F2FS文件系统的所有块大小都是4KBF2FS 代码隐式地将块大小链接到系统的页大小,因而F2FS不可能在更大的页的系统上运行,如 IA64 和 PowerPC

(2) 块地址是32位的,最大文件系统是2^(32+12) Bytes,也就是16TB(完全大于当前的 NAND flash 设备的大小)。

3.1.2 Segments

(1) 连续的Blocks集合成Segments,一个Segment的大小是512Blocks(也就是2MB);

(2) 每个Segment都有一个Segment Summary Block元数据结构,描述了Segment 中的每个Block的所有者(该块所属的文件及块在文件内的偏移)。Segment Summary主要用于在执行Cleaning操作时识别哪些Blocks中的数据需要转移到新的位置,以及在转移之后如何更新Blocks的索引信息。一个Block就可以完全存储512Blockssummary信息,每个blocks都有一个1 bit的额外空间用于其它目的。

(3) 2MB是最合适的Segment大小,太大不合适,太小又会造成存储summary信息的Block空间浪费;

3.1.3 Sections

(1) 连续的Segments集合成SectionSection中具有的segments个数是任意的,但是要满足是2的幂;默认情况下,一个Section大小等同于一个Segment2^0 Segments);

(2) 一个Section对应log structuring的一个区域“region”,log在使用下一个Section之前,通常要从头到尾将当前的Section填满数据;

(3) 清理器Cleaner一次处理一个Section

(4) F2FS中,任意时刻都有6个“打开的”Sections用于将各种不同种类的数据(元数据、数据)分别写入到各个Sections中,实现数据分离。这样便允许文件内容(数据)与其索引信息(节点,node)分离,允许F2FS文件系统根据各种启发式方法将Sections划分成三类:即“hot”、“warm”、“cold”。例如,目录数据被当做hot来对待,使其与文件数据分离,存放到“hotSection中。Cold数据是指那些很长时间内都不会改变的数据,因而装满Cold数据的Section就不需要执行Clean操作。对于hot节点(索引信息节点),一般更新很快,一段时间之后,装满 hot 节点的Section中的有效数据(alive data)就会很少,因而选择这样的Section进行Clean操作开销就很小(因为要转移的数据很少)。


3.1.4 Zone

(1) 连续的Sections集合成Zone。一个Zone可以包含任意整数个Sections。默认是一个Zone中包含一个Section

(2) 设置Zone的唯一目的是尽可能将6个打开的Sections位于Flash设备的不同的子设备中。理论上,Flash设备通常是由一组相互完全独立的子设备构成,每个子设备都可单独地处理I/O请求,不同子设备可并行处理I/O请求;如果Zone的大小与子设备大小对齐,6个打开的Sections可并行写入,充分利用设备的特性;

(3) Zone构成了F2FS的“主要(main)”区域。

3.1.5 Meta  Area

F2FS有一个“meta”区域,包含了各种不同的元数据(如之前提到的segment summary),这一部分不是采用标准的log-structured流水线方式管理,因而更多的工作留给了FTL去做。有三种方法管理对“meta”区域的写操作:

a)第一,有少量的只读数据(超级块)从来都不是不是在文件系统创建的时候立即写入;

b)第二,对Segment Summary Block 简单采取本地更新的方法。这种本地更新可能导致文件系统奔溃后数据块“修正”内容的不确定性,但对segment summary来说这都不是问题,segment summary blocks中的数据在使用前要进行有效性验证,如果有任何信息丢失的可能,它都将会在恢复进程中从其他source中恢复。

c)第三种方法,分配需求空间两倍大小的空间,使得每个block都有两个不同的位置:一个Primary,一个Secondary,任意时刻,两个位置的block仅有一个是live状态。因而LFSCopy-On-Write需求就可以通过向non-live位置的block写入更新后的block内容并且更新记录哪个位置的blocklive状态的方式简单实现。对于元数据来说,这种技术是实现快照功能的主要实现方法。当创建一个Checkpoint的时候,F2FS执行少量的Journaling更新到最后的组(last group),这在一定程度上减轻了FTL的工作。


文件(Files)、索引节点(Inodes)、数据块索引(Indexing)

1. 文件索引树结构

大多数现代文件系统都喜欢使用 B-trees 或类似的结构来管理索引(index)以定位文件中的 blocks。大多数文件系统中通过使用“extents”来减少文件数据块的总索引大小。F2FS 不采用 B-tree 结构管理索引,也不使用extents减少文件数据块索引的大小(虽然F2FS为每个节点(node)维护一个extent作为提示)。

2. 索引节点

管理数据位置的关键数据结构是“node”,与传统文件系统相似,F2FS 使用三种 nodeinode,直接 node,间接 nodeF2FS 分配4 KB 的空间给一个 inode,其中包括929个数据块索引指针,两个一级索引块(直接 node )指针,两个二级索引块(间接 node )指针,以及一个三级索引块(二级间接 node)指针。一个一级索引块(直接 node )包含1018个数据块指针,一个二级索引块(间接 node )包含1018个一级索引块(直接 node )指针,一个三级索引块(二级间接 node)包含1018个二级索引块(间接 node )指针。因此一个文件的最大大小是:

4 KB * (929 + 2*1018 + 2*1018*1018 + 1018*1018*1018) := 3.94 TB

3. 文件数据块索引

F2FS 使用索引树(如原始Unix文件系统和Ext3的索引树)索引数据块。Inode中包含了文件开始的一部分的数据块的地址列表,然后一些地址用于间接索引块以及二级和三级间接索引块。Ext312个直接索引地址以及三个间接索引块(一级、二级、三级)。F2FS 929个直接索引地址,2个一级间接索引块,2个二级间接索引块,1个三级间接索引块。允许寻址接近4TB的文件,也就是最大文件系统的1/4大小。

按大家最熟悉的Ext2Ext3的索引方式看,F2FS的索引树就是如下的结构:


4. 文件索引树对F2FS的意义

但是这种索引树机制有一定的代价——这也是其他文件系统抛弃这种索引方式的主要原因——但是这种方式对 LFS 却有好处。因为F2FS不使用 extents ,任意给定文件的索引树是固定的而且大小已知。这意味着,当数据块由于 cleaning 操作需要转移数据时,不可能因为可用 extens 发生改变而导致索引树变得更大(原来文件中每个 extent 很大,一个文件的索引树仅仅用少数几个 extents 就可完全表示,而新的存储部分每个可用 extent 都很小,要存储原来的文件就需要更多的 extents,导致文件的索引树变大)的情况产生——这可能会导致一种尴尬的情况产生就是 cleaning 的目的本来是要释放空间,而现在索引树变大却导致空间变小了。Logfs 文件系统也因为相同的原因,使用了许多相同的编排处理方式。

显然,所有这些需求都要求 F2FS  inode  Ext3 inode要大许多。因为Copy-on-write 不适用于小于块大小的对象,因而 F2FS 中每个 inode 占用的空间大小是一个 4 KB的块,该 4 KB 的空间中提供了大量的空间用于索引。甚至提供空间存储(基本的)文件名,或者名字之一,以及其父节点的 inode 号,这简化了在文件系统 crash 恢复过程中近期创建的文件的恢复操作,减少了为保证文件安全需要写入的数据块的数量。

5. 加速文件查找的Extent

Inode 中包含了一个 extent,它总结了索引树的某些部分,它说明该文件的某些范围的blocks在存储上是空间连续的,并给出该范围的地址。F2FS 文件系统尝试在此处表示文件中最大的 extent,使用其加速地址查找。例如,通常情况下文件是连续写入且无任何明显的暂停,这样可能的结果是整个文件构成一个 extent,使得没有必要进入文件的索引树查找。

6. NAT解决wandering Tree问题

任何基于 Copy-on-write 技术的文件系统的一个缺点在于,无论何时要改写一个数据块,该数据块的地址就会因为数据重写到其他位置而发生改变。然后,在索引树中该块的父节点也因此必须重写到其他位置,如此往复下去直到重写操作传播到索引树的根。LFS logging 特性意味着在恢复过程中向前回滚可以重建近期对索引树的修改,因而所有这些修改不必立即写到磁盘(只是写到 log 中),但是这些修改最终还是会写到磁盘的,这就将更多的工作丢给 cleaner 去做。

这是 F2FS 为了方便而使用其底层 FTL 去处理的另一个区域。“元数据”区域('meta' area)中的内容是一个 NAT——Node Address Table(节点地址表)。这里的节点是指inode 和间接索引块,以及用于存储扩展属性的数据块。当 inode 的地址存储在目录中,或者索引块存储在一个 inode 中或者其他的索引块中的时候,它存储的不是(存储的内容所在的)地址,而是其在 NAT 中的偏移。实际的(存储内容的)块地址是存储在 NAT 中对应的偏移处。这意味着当一个数据块被写入,仍然需要更新和修改指向该数据块的节点,但是修改该节点仅需更新对应的 NAT 项。NAT 是元数据的一部分,NAT 使用两个位置(two-location) Journaling(依靠FTL实现写聚合),因而不需要进一步的索引。

7. Inline技术支持情况

F2FS 目前不使用小文件内嵌(Inline)技术。针对这一技术的实际情况是:暂时还不支持 Inline 技术,但是很容易实现加入这一技术,并且这一技术迟早会加入到 F2FS 中。

8. 时间分辨率

很不幸,F2FS 没有足够空间存储64位的时间戳,也就是最小时间分辨率不是纳秒(ns),而是以秒(s)为时间分辨率。这可能导致2038问题,但时间戳分辨率问题应该会在未来的版本中解决。




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多