注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

中吴南顾惟一笑

成功法则就是那19个字

 
 
 

日志

 
 

Flash和SSD的一些特性  

2015-06-16 17:10:08|  分类: R&D |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

摘自《大话存储》

大话存储

从Flash芯片读取数据的过程
当需要读出某个Page时,Flash Controller控制Flash芯片将相应这个Page的字线组电势置为0,其他所有字线组的电势则升高到一个值,而这个值又不至于使电子穿过FG绝缘层到达FG。这种动作的结果是,所有Cell串的位线被导通以便外接从位线上提取电势状态,而所有字线电压被提高的Page其感应线均被断开导致感应线不能将对应Cell的电势传递到位线上,所以此时每个Cell串的位线所体现的电势值与待读出Page中所有Cell一一对应,再通过电路将每条位线上的电势值解码成1或者0从而传输到芯片外部,放置于SSD的RAM Buffer中保存,这就完成了一个Page内容的读出。SSD的IO最小单位为1个Page。

向Flash芯片中写入数据的过程
对Flash芯片的写入有一些特殊的步骤。Flash芯片要求在修改一个Cell中的位的时候,在修改之前,必须先Erase。Erase完成之后,Cell中全为1,此时可以向其中写入数据,如果遇到待写入某个Cell的数据位恰好为1的时候,那么对应这个Cell的电路不做任何动作,其结果依然是1;如果遇到待写入某个Cell的数据位为0的时候,则电路将对应Cell的字线电压提高到足以让电子穿过绝缘体的高度,这个电压被加到Control Gate上,从而对Cell中的FG进行充电,充电之后,Cell的状态从1变为0,完成了写入,这个写0的动作又叫做“Programm”,即对这个Cell进行了Programm。

将待写入Cell的字线电压升高到一定值,对Cell充电,充电成功,则在Cell的位线上会感应出一定的电势值,通过检测这些值来判断电荷是否已经被充入,如果位线上并没有感应出正确的电势,则表示对应这个位线的Cell串中对应的Cell可能已经损坏。SSD会以Page为单位进行写入操作,写完一个Page,再写下一个Page。


Flash芯片使用一种叫做“浮动门场效应晶体管”的晶体管来保存数据。每个这样的晶体管叫做一个“Cell”,即单元。有两种类型的Cell:第一种是Single Level Cell(SLC),每个Cell可以保存1B的数据;第二种为Multi Level Cell(MLC),每个Cell可以保存2b的数据。MLC容量为SLC的两倍,但是成本却与SLC大致相当,所以相同容量的SSD,MLC芯片成本要比SLC芯片低很多。此外,MLC由于每个Cell可以存储4个状态,其复杂度比较高,所以出错率也很高。不管SLC还是MLC,都需要额外保存ECC校验信息来做数据的错误恢复。

Erase Before Overwrite
如果要向某个Block写入数据,则不管原来Block中是1还是0,新写入的数据是1还是0,必须先Erase整个Block为全1,然后才能向Block中写入新数据。这种额外的Erase操作大大增加了覆盖写的开销。
如果更改某个Block中的某个Page,那么此时就需要Erase整个Block。在Erase之前,需要将全部Block中的数据读入SSD的RAM Buffer,然后Erase整个Block,再将待写入的新Page中的数据在RAM中覆盖到Block中对应的Page,然后将整个更新后的Block写入Flash芯片中。可以看到,这种机制更加大了写开销,形成了大规模的写惩罚。这也是为何SSD的缓存通常很大的原因。
SSD的这种写惩罚被称为Write Amplification(写扩大),当SSD当向Flash中的Free Space中写入数据时,并没有写惩罚,因为Free Space自从上次被整盘Erase后是没有发生任何写入动作的。
存储介质如何知道哪里是Free Space,哪里是Occupied Space呢?只有文件系统知道,除非文件系统通过某种途径通告存储介质。SSD会将曾经被写入的块的位置记录下来,记录到一份Bitmap中,每一比特表示Flash中的一个Block。对于文件系统而言,删除文件的过程并不是向这个文件对应的存储介质空间内覆盖写入全0或者1的过程,而只是对元数据的更改,所以只会更改元数据对应的存储介质区域,因此,删除文件的过程并没有为存储介质自身制造Free Space。所以说,对于SSD本身来讲,Free Space只会越来越少,最后导致没有Free Space,导致每个写动作都产生写惩罚,类似CoW,而且Copy和Write的很有可能都是一些在文件系统层已经被删除的数据,写性能急剧下降。

由于电路设计原因,一个Page中的多个位,也就是Cell,如果有的正在充电(写入0),有的正在放电(写入1),那么会产生不可忽略的干扰导致问题,正因为这个限制,所以必须取舍,要么就对整Block中的所有Cell充电(写0),要么就对其整体放电(写1)。最后,研发人员下定决心,就取后者吧,每次先预先将整个Block擦成全1,然后再接受IO,IO数据中遇到为1的位,对应的Cell不动作,遇到为0的位,则对应的Cell进行充电。这样,不管任何时候,对于一个Block中的所有Cell来讲,只有“全部在放电”或者“全部/部分在充电”这两个状态,不会产生干扰。

那么为何非要一次擦一整个Block呢?一次擦一个Page不行么?粒度和效率问题。粒度越小,管理开销就越大,表现在导线与电路开销和能耗方面,可擦除粒度越小,需要的导线和电路就越多;由于SSD使用一种办法来避免写惩罚以及Wear Off,而这种办法的使用,需要大粒度的Erase以便节约时间和提高效率,同时不增加写惩罚。

当Block被擦除之后,SSD控制器可以先向其中写入若干Page并再连续追加(不能跳跃)写入剩余的Page而不需要再次擦除这个Block。SSD控制器会记录每个Block中的大段连续空余空间。一般来讲,控制器都是尽量一次写满整个Block的从而可以避免很多额外开销。


Wear Off

随着FG充放电次数的增多,二氧化硅绝缘层的绝缘能力将遭到损耗,最后逐渐失去绝缘性,无法保证FG中保有足够的电荷。

Cell损坏之后的表现是只能表示1而无法再被充电并且屏蔽住电子了

SSD是如何判断出这个Cell已经不能保存数据的呢?在Write操作中,会向Cell中充电,成功后会在对应的Bit Line中体现出Cell当前的电势,通过检查这个电势表示的位是否与待写入数据中对应的位一致来判断,一致则判断为完好,不一致则损坏。如果遇到写入数据位为1的情况,那么写入过程中对这个Cell不会有任何动作。如果这个Cell已经损坏,即不能被充电或者充电量太低以至于不能感应出足够的电势,那么当数据被写入之后,依然被判断为完好。这虽然与实际不符,但是不影响使用,一旦这个实际已经损坏的Cell在下次被更改为0,就会被判断出已损坏。

损坏的Cell将拖累这个Cell所在的整个Page被标记为损坏,因为SSD寻址和IO的最小单位为Page。损坏的Page对应的逻辑地址将被重定向映射到其他完好的预留Page,SSD将这些重定向表保存在ROM中,每次加电均被载入RAM以供随时查询。

 

SSD私自保留的空间
为了防止文件系统将数据写满的极端情况,SSD干脆自己预留一部分备用空间用于重定向写。这部分空间并不通告给操作系统,只有SSD自己知道,也就是说文件系统永远也写不满SSD的全部实际物理空间,这样,就有了一个永远不会被占用的一份定额的Free Space用于重定向写。

Delay Write是一种存储系统常用的写IO优化措施。比如有先后两个针对同一个地址的写操作先后被控制器收到,而在W1尚未被写入永久存储介质之前,恰好W2进入,此时控制器就可以直接在内存中将W2覆盖W1,在写入硬盘的时候只需要写入一次即可。这种机制为“写命中”的一种情况。它减少了不必要的写盘过程,对于SSD来讲,这是很划算的。

然而,如果一旦遇到这种IO顺序比如W1、R2、W3,如此时控制器先将W3覆盖到W1,然后再处理R2的话,那么R2原本是应该读出W1的内容的,经过Delay Write覆盖之后,却读出了W3的内容,这就造成了数据不一致。所以,控制器在处理Delay Write时要非常小心,一定要检测两个针对同一个地址的写IO之间是否插有针对同一个地址的读IO,如果有读IO,首先处理读,然后再覆盖。

Combine Write是另一种存储系统控制器常用的写IO优化方法。对于基于机械硬盘的存储系统,如果控制器在一段时间内收到了多个写IO而这些写IO的地址在逻辑上是连续的,则可以将这些小的写IO合并为针对整体连续地址段的一个大的IO,一次性写入对应的磁盘,节约了很多SCSI指令周期,提高了效率。对于SSD来讲,由于SSD中的逻辑地址本来就是被杂乱地映射到可能不连续的物理地址上的,但是并不影响多少性能,所以,SSD控制器可以整合任何地址的小块写IO成一个大的写IO而不必在乎小块写IO针对的逻辑地址是否连续。整合之后的大写IO被直接写向一个Free的Block中,这样做大大提高了写效率。


TRIM
TRIM是ATA指令标准中的一个功能指令,可以让文件系统在删除某个文件之后实时地通知SSD回收对应的空间(而非定期执行垃圾清理)。
TRIM可以使SSD起死回生,经过实际测试,开启了TRIM支持的SSD,在操作系统TRIM的支持下,可以成功地将性能提高到相对于SSD初始化使用时候的95%以上,写惩罚倍数维持在1.1倍左右。

影响一块SSD寿命和写入性能的最终决定因素就是Free Space,而且是存储介质自身所看到的Free Space而不是文件系统级别的Free Space。但是SSD自身所认识的Free Space永远只会少于文件系统的Free Space,并且只会越来越趋于0。所以,要保持SSD认识到自身更多的Free Space,就必须让文件系统来通知SSD,告诉它哪些逻辑地址现在并未被任何文件或者元数据所占用,可以被擦除。
所有SSD厂商均会提供一个工具,称为“Wiper”,在操作系统中运行这个工具时,此工具扫描文件系统内不用的逻辑地址,并将这些地址通知给SSD,SSD便可以将对应的Block做擦除并回收到Free Space空间内。如果用户曾经向SSD中写满了文件随后又删除了这些文件,那么请务必运行Wiper来让SSD回收这些垃圾空间,否则就会遭遇到大写惩罚。

Wiper并不是实时通知SSD的,这个工具只是一次性清理垃圾,清理完后可以再次手动清理。所以,这个工具需要手动或者设置成计划任务等每隔一段时间执行一次。

这种垃圾回收与上文中的那种内部垃圾回收不在一个层面上,上文中所讲的是SSD内部自身的重定向管理所产生的垃圾,而本节中所述的则是文件系统层面可感知的垃圾,被映射到SSD内部,也就变成了垃圾。

Wear Leveling
为了避免同一个Cell被高频率擦写,SSD每次针对某个或者某段逻辑LBA地址的写都写到SSD中的Free Space中,即上一次全盘Erase后从未被写过的Block/Page中,这些Free Space已经被放电,直接写入即可,无须CoW。如果再次遇到针对这个或者这段LBA地址的写操作,那么SSD会再次将待写入的数据重定向写到Free Space中,而将之前这个逻辑地址占用的Page标记为“Garbage”,可以回收再利用。等到Block中一定比例(大部分)的Page都被标记为“Garbage”时,并且存在大批满足条件的Block,SSD会批量回收这些Block,即执行CoW过程,将尚未被标记为“Garbage”的Page复制到RAM Buffer,将所有Page汇集到一起,然后写入一个新Erase的Block,再将所有待回收的Block进行Erase操作,变成了Free Space。SSD这样做就是为了将写操作平衡到所有可能的Block中,降低单位时间内每个Block的擦写次数,从而延长Cell的寿命。

重定向写的设计既解决了Wear Off过快问题,又解决了大倍数写惩罚问题(因为每次写都尽量重定向到Free Space中,无须CoW)。但是,正如上文所述,SSD自己认为的纯Free Space只会越来越少,那么重定向写的几率也就会越来越少,最后降至0,此时大倍数写惩罚无可避免。

由于Page的逻辑地址对应的物理地址是不断被重定向的,所以SSD内部需要维护一个地址映射表。可以看到这种设计是比较复杂的,需要SSD上的CPU具有一定的能力运行对应的算法程序。这种避免Wear Off过快的重定向算法称为Wear Leveling,即损耗平衡算法。

Wear Leveling的实现方法随不同厂商而不同,有些以一块大区域为一个平衡范围,有些则完全顺序地写完整个SSD的Free空间,然后再回来顺序地写完整个被回收的Free空间,无限循环直到Free空间为0为止。传统机械硬盘中,逻辑上连续LBA地址同样也是大范围物理连续的,但是对于SSD,逻辑和物理的映射随着使用时间的增长而越来越乱,好在SSD不需要机械寻址,映射关系乱只会影响CPU计算出结果的时间而不会影响数据IO的速度,而CPU运算所耗费的时间与数据IO的时间相比可以忽略不计,所以映射关系再怎么乱也不会对IO的性能有多少影响。

  评论这张
 
阅读(97)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017