FTL是个啥?
FTL指Flash Translation Layer(闪存转换层),这玩意儿的本职工作是完成Host的逻辑地址到Flash的物理地址的转换。
controller每把一笔数据写入Flash中时,便会记录下该数据的逻辑地址到物理地址的映射关系,这样当Host想要读取这笔数据时就会根据这个映射读取到真实的数据。
首先说明一下闪存的特性:
1. 闪存块需要先擦除才能写入,不能覆盖写。
2. 闪存块是有寿命的。每擦除一次寿命便会减少一点。
3. 闪存块的读取次数是有限的。读的次数多了会造成读干扰问题。
4. 闪存的数据保持是有时限的。高温时数据保持时间会缩短。
5. 闪存天生就会有坏块。使用过程中会产生新的坏块。
6. MLC和TLC 会有 lower page corruption的问题。
针对闪存的以上特性,FTL在完成本职工作逻辑地址到物理地址转换的同时,还要具有十八般武艺:
垃圾回收(Garbage Collection),磨损平衡(Ware Leveling),坏块管理,读干扰处理,数据保持处理等事情。
FTL十八般武艺之本质工作---映射管理
映射有基于块映射、基于页映射和混合映射。
基于块映射Host在读写小尺寸数据(随机性能)时性能较差,一般用在U盘中(ps:不要惊讶,U盘中也用到FTL的),所以U盘不适合装系统,适合用来读写大尺寸数据的数据传输用。
基于页映射对小尺寸数据(随机性能)有很好的性能,但是由于闪存的页要比闪存块多的多,需要更多的空间来存放映射表。为了追求更好的随机性能(操作系统对这个很在意)所以SSD都采用页映射。
混合映射的性能介于上边二者之间,当然存放映射表所用的空间也介于二者之间。
SSD内部FW维护了一张逻辑地址到物理地址的映射表(Map Table)。用户每写入一个逻辑页就需要更改一次MT;当读取一个逻辑页时,SSD会查找映射表中该逻辑页对应的物理页,然后再访问Flash读取所要的数据。
一般映射的逻辑页的大小为4KB,物理地址的大小为4Byte,那么一个256GB的SSD的映射表大小为:256GB/4KB*4B = 256MB,也就是说映射表的大小是SSD容量的1/1024。
为了存放这个映射表,SSD一般有两种设计方案:DRAM(带DRAM的)和DRAM-less(不带DRAM的)。带DRAM的一般会把缓冲数据和映射表统统存放在DRAM中,优点是查找更新映射表迅速,性能较好,劣势是多了一个DRAM,成本和功耗上升,当前的主流SSD是该方案;DRAM-less的会将少部分的映射表放在片内的SRAM上,其余部分的映射表则会放在Flash中,这种方案好处是节省了DRAM的成本和功耗,但是读写Flash要比读写DRAM要慢得多,所以速度上不如DRAM方案,性能较差,当前入门级的SSD多采用这种方案。
一个小问题:我们都知道DRAM掉电数据是会丢失的,那么数据表怎么办?
答案是在SSD掉电之前,它会把映射表写入到Flash中去的,下次上电初始化时需要重新把映射表读出来放在DRAM或SRAM中。也就是说不管DRAM或DRAM-less,Flash中都需要储存映射表的。
FTL十八般武艺之重要内功---收垃圾(Garbage Collection)
这年头收垃圾也成特色技能了,还是重要内功。。。哈哈
垃圾回收,就是把某一个闪存块上的有效数据读出来,写入另一个数据块中,然后擦除原来的闪存块,使之可用。
也许你会问,数据在原来的闪存块上待的好好的,为什么要费事吧连的读出来写入另外的块中呢?原因是原来闪存块上的垃圾(无效数据)太多了!如前文讲道,闪存块需要先擦除才能写入,不能覆盖写。如果一个块上只有一点点有效数据占着整个数据块,那么就需要把有效数据搬移出来,把这个块擦除掉使之变成可用状态,从而提高块的使用率。
也许你又会问,为啥子数据会无效呢?原因还是因为闪存的特性导致的,为了延长每个闪存块的寿命,就需要均衡每个数据块的擦除次数,为了均衡每个数据块的擦除次数,数据写入时候就需要均衡的写入每个块,而不能照着一个块往死了写。当用户空间里的数据写满后,就需要把数据写备用空间(SSD的实际容量都比标称容量大,多出来的部分就是备用空间),因为备用空间对操作系统是不可见的,那么每往备用空间写一笔数据就会在用户空间产生一笔无效数据(垃圾)。
江湖传言:SSD越用速度越慢。很不幸,这是真的,而且是有依据的。新盘没有垃圾可收,所以速度快!用久了产生的垃圾就多了,就需要用内功把垃圾逼出来,当然速度就慢下来了。
FTL十八般武艺之---磨损平衡(Ware Leveling)
其实在垃圾回收的时候已经提到磨损平衡的原因了:为了延长每个闪存块的寿命,就需要均衡每个数据块的擦除次数,为了均衡每个数据块的擦除次数,数据写入时候就需要均衡的写入每个块,而不能照着一个块往死了写。
那么,一个闪存块的寿命有多长呢?
SLC:10万次
MLC:1~10千次
TLC:几百次~2千次
QLC:< TLC
3D:< QLC
所以,磨损平衡很重要!接下来几个概念:冷数据(Cold Data),热数据(Hot Data)
年老块(Old Block),年轻块(Young Block)
所谓__冷数据__就是用户不常更新的数据,比如音视频,只读数据等;相反__热数据__就是频繁更新的数据,比如软件使用等,会产生很多垃圾。
所谓__年老块__是指擦写次数比较多的块;相反__年轻块__则指擦写次数比较少的块。ps:每个块都有EC(Erase Count),年轻还是年老SSD一下就可以看出来。
SSD一般有两种(Ware Leveling)算法:动态磨损平衡(Dynamic WL)和静态磨损平衡(Static WL)。动态磨损平衡算法基本原理是把热数据写到年轻块上;静态磨损平衡的基本思想是把冷数据写到年老块上。这里可以停下来先品味一下这样的做的原因。
DWL好理解:写数据时找年轻的块写,避免往老年块上写数据,各个块就能保持一个比较均衡的值。
SWL呢?冷数据基本不更新,它所占用的块擦写次数就不会增加,而其他块会被经常写入数据,块擦写次数是会增加,这样就导致了擦除不均衡,SSD最不喜欢这个了。所以需要把冷数据搬到老年块上,让年轻块替代老年块的工作。