FTL详细资料

FTL产生过程

如果仅仅是SSD的使用者,一定不会在意在SSD内部居然还存在一个复杂的软件层Flash Translation Layer(FTL)。其实就是这个FTL才是SSD固态硬盘的软件核心技术。正因为有了FTL,NAND Flash才能被当成硬盘来使用;文件系统才可以直接把SSD当成普通块设备来使用。由于FTL是SSD设计厂商最为重要的核心技术,因此,没有一家厂商愿意透露这方面的技术信息,并且也一直没有业内的技术规范、标准存在。

FTL的重要程度在于决定了一个SSD的使用寿命、性能和可靠性。一旦FTL出现问题,那么就会导致数据读写发生错误,更为严重的是SSD盘无法被访问。优秀的FTL不仅能够提升Flash存储的使用寿命,而且还可以最优化读写性能。因此,在Flash固态存储中,FTL是一个最为重要的管理NAND Flash的软件层。

在学术界,这十年来有很多文章在讨论如果实现一个高效的FTL,例如,在有限硬件资源的环境下如何实现mapping?如何实现buffer的管理?如何实现高效的Garbage Collection?如何实现磨损均衡Wear-leveling?如何实现NAND Flash芯片之间的数据冗余(RAID on Chip)?很多算法的提出非常具有建设性和现实意义,对工业界具有很好的指导价值。

这里主要想谈一下FTL内部mapping的机制。从文章《采用NAND Flash设计存储设备的挑战在哪里?》了解到基于NAND Flash研制存储设备是有很多挑战的,最大的问题在于NAND Flash不能像内存那样随意的写入。NAND Flash在Page页写入之前必须要将Page页所在的Block块擦除。如果研制SSD的时候严格按照这个准则,那么设计开发出来的SSD是不能用的。其一,按照这种方式进行写操作,写入的性能将会很差,其bottleneck限制在块擦除上(块擦除时间在ms级);其二,不断的对同一Block块进行擦除操作,那么该块将会在短时间内磨损写坏,并且极易导致存储在该块上的数据丢失。因此,在设计SSD时最主要的任务就是解决NAND Flash的这种“写时擦除”问题。

技术是相通的,在90年代提出的Log-structured File System(LFS)思想和NAND Flash简直是天生一对。当初设计Log-Structured File System最主要的想法是利用机械磁盘出色的顺序写性能,避免糟糕的随机写问题。Log-structured File System在机械硬盘的时代有一定的应用局限性,问题在于采用log数据布局的方式之后,读性能变得很差。因此,只有在大块数据读写(对象存储)的环境下,log-structured File System才变得合情合理。在NAND Flash介质上,不存在机械硬盘随机读写的问题,因此,log-structured的数据布局方式不会引入任何性能问题,反而能够解决NAND Flash的“写时擦除”问题。

采用Log-structured的方式之后,NAND Flash可以采用out-of-place的数据更新方式。所有的数据更新都不会写入原来的page页,而是重映射写入一个新的Page页。在这个思路的引导,很显然所有NAND Flash的存储资源可以按照物理Page页的方式管理起来,而用户可见的空间则是一个连续逻辑Page页连接起来的地址空间。FTL的一个关键任务就是建立逻辑Page和物理Page之间的映射关系,并且在数据写入时重新分配物理Page页。在这种机制的支撑下,SSD的写性能可以大为提高,写延迟可以控制在200us的级别。

引入log-structured的机制之后,逻辑page和物理page之间存在映射关系,FTL负责物理page页的分配。考虑到每个Block块都是有擦除寿命的,因此,如果想要提升SSD的整体使用寿命,那么需要将块擦除次数均衡到所有块上去。这个工作就交给了FTL中的块分配器。均衡擦除次数这个工作其实是挺麻烦的事情,其最大的挑战在于记录每个块的擦写次数,并且这些信息需要持久化存储。

众所周知,log-structured数据布局方式最大的问题在于垃圾回收(garbage collection),由于page页从来不会被in-place-update,因此,当一个page被重映射之后,老的page页就会变成无效,等待Garbage Collection回收该页。在NAND Flash中,GC最大的挑战在于以块为单元进行擦除,而不是Page页。换句话说,GC需要将一个Block块中的所有Page页同时回收,这个限制导致GC在回收一个Block的时候会进行数据迁移操作。过多的数据迁移操作会影响SSD的使用寿命,并且会影响到整体的读写性能。因此,优化Garbage Collection成了FTL最头疼的一个问题。最容易想到的一个优化方法是将冷热数据分开存储到不同的Block块中,这样在数据回收的时候,可以尽最大可能减少有效数据的迁移。

Log-structured File System为NAND Flash的FTL设计提供了一个非常好的思路。但是,要想在SSD这样一个硬件资源非常有限的平台上实现FTL的所有功能还是很有挑战的。举个例子,log-structured的方式是需要进行Page页映射的,映射操作需要建立映射表。如果内存太小,那么对映射表的大小就提出了需求。假设一个SSD具有1TB的容量,那么如果采用4KB Page映射的方式,每个page映射需要4字节描述,那么至少需要1GB的内存容量来存放映射表。在嵌入式系统中,1GB的内存容量是庞大的。因此,为了避免过多的占用内存容量,拍脑袋可以想到Block映射的方式。假设一个Block容纳128个Page页,那么一下子可以将映射表容量缩减到原来的1/128。但是这种Block映射的方式效率实在太低,会导致大量的数据迁移,从而缩短了SSD的使用寿命。

A. LBA和PBA究竟是对应page还是block?

解答:如果我们把LBA和PBA都设置成page大小,这也叫做page-level mapping,这和我们写入颗粒一致,很灵活。但这么小的粒度会带来一个问题:逻辑对应表太大!想象一下,我们有个64GB的Die,每个page只有4KB,我们的对应表需要64*1024*1024 * 4 /4 = 64MB!这个绝对不能接受。那么按照block,也就是block-level mapping呢? 会不会好些呢?至少占用空间好了很多,但是因为写入时不清楚page情况,往往要整块擦除,效能会大大下降。有没有更好的办法呢?实际使用中常用的是log-block mapping,它从我们现代的log文件系统中学到经验,也充分利用了page和block的不同特性。

所以,为了减小映射表的容量,一个比较可行的方式是采用Hybrid映射方式。

Hybrid-level mapping的思想是将映射操作分成两级。第一级是data-log,所有数据首先写入log,当log写满之后,再将log中的数据合并至data-block;第二级是data-block,用来存放从log中合并过来的数据。对于data-log,由于数量有限,因此可以采用page-level mapping的方式;对于data-block,由于存储容量比较大,因此,可以采用block-level mapping的方式。Hybrid-level mapping可以很好的平衡内存使用和mapping效率之间关系,因此,学术界也对此提出了很多优化的方法。

FTL详细资料_第1张图片

其中,一个比较有意思的方法是locality aware的hybrid-level mapping思想,其原理如上图所示。从结构上讲,其大致可以分成传统Hybrid-level mapping的双层结构。写入的数据首先进入data-log。不同的地方是,data-log被分成了random-log-buffer和sequential-log-buffer。写入的数据根据locality-detector被分流至random-log-buffer或者sequential-log-buffer。其中random-log-buffer采用page页映射的方式,sequential-log-buffer直接采用block映射的方法,这样可以进一步降低内存使用量。当log-buffer中的数据满了之后,需要合并到data-block。合并的方法和传统的相同,被分成switch、partial-merge和full-merge。

FTL是NAND Flash存储的底层核心技术之一,由于NAND Flash本身存在很多问题,导致FTL的设计、实现都会存在很多的挑战。上面只是简单的阐述了一下FTL中mapping的一些棘手问题和一些解决思路,抛砖引玉,揭开了神秘面纱,往里面瞅上了一眼。这一看其实会发现,FTL虽小,但是难度丝毫不比一个文件系统小。


FTL详细介绍

和传统磁盘相比,Nand Flash存储设备存储延迟低、功耗低、更高的存储密度、抗震型号更好和噪声低。但是,由于Nand Flash的特性影响(读写擦的单位不一致,每个块有P/E次数限制),Nand Flash不能直接通过简单的接口转换就拿来使用。所以我们需要在Nand Flash上增加一个管理软件FTL(Flash Translation Layer)进行管理,对外就是一个黑盒子,上层应用可以通过逻辑地址来对这个黑盒子进行访问。

图1

如上图,上层应用通过逻辑地址来访问存储设备,FTL把不同的逻辑地址映射到Nand Flash中的不同位置,FTL简单来说,主要就是映射管理。
固态存储相对于传统磁盘的一些特点:
  1. 异处更新(out-of-place Update)。正如之前所说,Nand Flash编程操作只能把存储单元从1变为0,所以在重新编程之前需要进行擦除操作。而且编程以页为单位,擦除以块为单位(一个块包括多个页)。如果使用同处更新(in-place update),就是把同逻辑地址重复更新到同样的位置上,那么每一次更新,都需要先进行一次擦除操作。由于擦除操作耗费时间和对Flash有损伤,所以一般FTL使用异处更新,把更新的数据映射到一个新的位置上。

    如下图,上层应用先写逻辑地址0、1,FTL把数据映射到Nand Flash的物理块0、1页上,然后上层应用又写逻辑地址0,此时物理块0第0页不能重新编程,所以FTL把数据存放在物理块0的第2页上。

    图2

  2. P/E次数有限制。之前有提到,Nand Flash每个块是有擦除次数限制的,在擦除一定次数后,这个块会变得不稳定,编程进去的数据容易出错,甚至会擦除失败。

  3. 性能更好。和传统机械硬盘不同,Flash存储是没有机械设备的,比如说不需要寻道,对所有的地址访问开销都一样,特别是在随机读性能上,SSD远远好于传统机械硬盘。按这个道理,Flash设备随机访问和顺序访问的速度是一样,但现实上,Flash支持Cache操作,在顺序访问中可以提前把下一个页的数据读取放到内部寄存器中,可以更快响应读请求。所以在顺序访问上速度要比随机访问要快的。

  4. 读、写速度不一致。如之前文章描述的,把电子从浮动门中吸进去(写操作)比检测浮动门电场状态(读操作)要耗时。所以FTL在管理时,尽量减少写和擦除的操作。

FTL功能
  1. 地址映射管理。闪存设备对外是一个黑盒子,里面集成了Nand Flash和FTL等,上层应用使用逻辑地址来访问,FTL把逻辑地址映射到不同物理地址上,管理着每个逻辑地址最新的数据存放的物理位置,如图1。
  2. 垃圾回收。随着数据的写入,闪存设备上有些块的部分数据已经无效了,需要把有效的数据从块上搬走,然后擦除用来接收新的数据。
  3. 磨损均衡和坏块管理。因为每个块的P/E次数是有限的,某些块可能被重复使用而损坏了,而有些块数据很少被访问,所以一直没有进行操作过。为了避免这种情况,FTL加入磨损均衡的功能,大致是通过控制垃圾回收和空块池的管理,从而平衡每个块的使用次数,最理想是所有块一起达到磨损阈值。
    由于Flash本身就存在部分坏块,在使用的过程中部分块会变坏,所以FTL在管理的时候需要避开这些无用块,把使用后变得不稳定块上的数据及时拷贝到稳定位置。
FTL研发关注点
  1. 映射管理性能。映射分为两种:逻辑地址到物理地址映射,成为直接映射;物理地址到逻辑地址映射,称为逆映射。大部分时候使用的都是直接映射,直接映射可以可能保存在SRAM中,也可能存放在Flash中。逆映射需要通过扫描Flash来建立映射关系,因为逆映射关系存放在Flash页的冗余空间中。可见,映射关系存放在SRAM中时获取对应关系速度是最快的,但由于SRAM资源比较紧张,所以会把所有映射关系存放在Flash中,软件只会加载使用的那段映射关系。逆映射需要扫描Flash来建立映射关系,所以速度最慢,一般用于特殊情况映射关系的恢复,比如说操作过程中断电了,或者某张映射表格所在的物理页坏了,需要重建。
    映射影响着我们数据的存放,比如说需要区分顺序数据和随机数据,随机数据可能区分为热数据、冷数据。如果把热数据和冷数据存放在同一个块中,由于热数据更新频繁,导致物理块有效页利用率不高,把此块进行垃圾回收时,要把其中冷数据有效页拷贝到其它地方,导致写放大。如果冷热数据区分开,可以避免在垃圾回收中回收到冷数据。
    映射管理是FTL中最重要的一点。
  2. 垃圾回收效率。垃圾回收需要考虑到冷热数据、磨损平衡和读写延迟。回收过程中把热数据和冷数据混合在一个块中,会导致冷数据的频繁读、写,加剧Flash损耗和影响性能。而且,热数据会被经常更新,在垃圾回收流程中应该避免回收热数据块。所以垃圾回收流程,需要综合考虑几大方面。
  3. 读写延迟。 读写延迟主要是指上层应用发送读写指令,设备处理、回复数据的时间。理想情况是,收到指令,软件在RAM中找到映射关系,返回数据。事实上影响的因素很多,比如说存在后台操作,在指令执行中间,软件可能进行垃圾回收,不能及时响应命令,如果垃圾回收流程控制不好,会造成上面这种情况,写速度波动很大,给人感觉就是在打CS,时而流畅,时而卡顿。
  4. SRAM需求。SRAM价格比较高昂,所以一般产品会严格控制SRAM的大小。如果SRAM足够大,可以把映射信息都保存在SRAM上,也把Flash中的数据都读取到SRAM上,性能是最好的(此外最好得有个备用电源或者超级大电容,意外掉电时可以把SRAM中被更新的数据写回Flash~)。事实上SRAM大小远远不够的,所以有块管理算法、混合管理算法和把映射关系存放在Flash中的方案,缓存上层应用数据也要考虑把部分冷数据回写到Flash中。
  5. Flash并行操作。闪存设备底层,每片Flash可以进行Multi Plane操作,多片Flash间同时操作,也可能有多通道可以并行操作。这些操作可以大大加速对Flash的访问速度,有点类似于RAID技术。 以上提到的FTL基本功能是相互关联的。比如说,上层应用写数据到某个逻辑地址上,地址映射管理在空块池中获取一个物理块来接收数据,然后触发了垃圾回收。垃圾回收在选择物理块的时候需要考虑到块的磨损情况、是否坏块,在回收这个块的时候需要使用并行操作,提高回收速率。
  6. 异常处理。在Nand应用场景中,比如说SSD、U盘、eMMC,均存在一些突然断电的情况。如何在突发掉电的情况后恢复数据,保持映射关系正常。比如说,RAM中缓存着最新的映射关系,没有保存在Flash中,此时掉电后,如何在下次上电后把RAM中的映射关系恢复;如何保证当前找到的映射表格是最新的等等。还有规避Flash特性造成的错误,如驻留错错误(Data Retention)、Disturb。

关于FTL的疑惑:

1、F2FS是否绕过了FTL层直接操作的NAND flash?因为F2FS中提供了类似FTL层的GC、磨损均衡、映射等操作??

自我解答:我认为F2FS自带了FTL的功能,不需要传统的FTL的转换,可以直接操作raw flash设备。
因为F2FS是为flash文件系统专门设计的,而对于传统的磁盘文件系统不是为Flash而设计的,如果直接在Flash上运行会很快使Flash局部老化而丢失数据,或崩溃。另外由于FLASH的块比较大,如果直接映射成块设备的话,空间利用率低。

FTL的作用就是解决负载均衡与提供适合传统文件系统的,大小合适(如512字节)的块设备。
如图所示
FTL详细资料_第2张图片

你可能感兴趣的:(f2fs,linux内核,信息存储理论,FTL,f2fs,flash)