NAND闪存的写入放大

NAND闪存的写入(P/E循环)次数有限,SLC的量级是1万-10万次,而MLC普遍只有3000-5000次,因此围绕SSD可靠性的争议和研究就没停止过,随便搜索有过SSD的资料见的最多的就是讨论SSD可靠性(reliability)的文章。

当然,也有一种说法称即便只有3000次写入寿命,60GB SSD的写入数据寿命也有3000*60GB=180TB,120GB也有360TB,其他更高容量的SSD写入量就更大了,日常使用中谁有这么多的写入操作,操作系统大都是读取操作而已,因此SSD寿命问题不足为虑。

这种解释有其合理性,但是了解过SSD实际写入操作之后就应该明白写入数据寿命的计算方式是基于一种理想状态—需要写入多少数据就实际写入多少数据,但是SSD中这两个数据并不是相等的。

还是看前面的例子,1234.txt从4B大小增加到8B大小名义上只多了4B的写入量,这是本机写入的数据量,HDD上直接覆写就可以了,但是SSD的写入是这样的:重新写入8B数据、清空block时把这8B数据又拷贝、写入了一次,实际写入量是16B,期间有两次写入、一次读取以及一次擦除操作。

在SSD写入过程中,SSD实际需要写入的数据量跟本机写入的数据量是不一致的,说得专业一点就是SSD写入过程中数据被无谓增加了的,这就是SSD的写入放大(Write Amplification)问题,二者存在一个比值叫做写入放大率(Write Amplification Factor,简称WAF)

WAF=SSD实际写入的数据量/本机写入的数据

WA=1的情况就是上面计算SSD写入寿命的理想状态,但是现实跟理想是有差距的,而且上面的例子将page和block都简化了,只是有助于理解SSD的写入特性,如果以实际的4KB page、256KB block(64个page)来算,并且其中63个page已经写入了数据,真正的写入放大是这样的:

Wiki上有关写入放大的解释

  当前block有63个page写入了数据,还留下4KB空间,此时如果写入4KB数据,理论上正好填满整个block,但是SSD不能直接覆盖写入数据,其他63个page的数据必须先复制到内存中,然后将整个blokc清空,要写入的这个4KB数据会在内存中与前面的63个page中的数据混合到的一起,然后再重新写入到一个block中。

在这个过程中,本机写入的数据是4KB,但是SSD实际写入的则是256KB,是前者的64倍,WAF写入放大率就是64,这还是一个block的情况,如果SSD是内部多颗die组建了RAID 0模式,那么实际擦除和写入的数据就不再以block为单位,而是以band为单位进行擦除和写入,假如是20颗die,那么要擦除和写入的数据量也会是原来的20倍,写入放大会更严重。

写入放大不仅无谓地提高了NAND闪存的写入次数,还会影响性能,因为另外的63个page还多出了一次读取数据的过程,SSD的IOPS通常都是数千到数万级的,我们以1000来算,即便只是复制了252KB的数据,写数据的同时读取速度也会有252MB/s,这个多余(但对SSD来说是必须的)的过程消耗了大量带宽,SSD的性能自然会下降。

也有人会说一句:“小编,你傻啊,那个4KB数据为什么非得写在有数据的地方,写在空白的block区域不就没事了,WAF就是1啊”,不错,这个问题也是解决或者说减少WAF的因素,在空盘上连续写入的情况下是不存在写入放大情况的,SSD空白block越多写入放大就越少,再往下引申就是TRIM指令生效越多,写入放大也越少;OP预留空间越多写入放大也越少(但是这又会影响用户的可用空间),GC垃圾回收实际上也是在重写数据,也会增加写入放大,但是GC又不可或缺。

减少写入放大是提高SSD可靠性的必要工作,在这方面Intel的SSD是做的比较好的,因为写入放大的概念就是Intel提出的,他们的研究也更深入。

以上图为例,Intel宣称其SSD的WAF只有1.1,WLF(耗损均衡指数)为1.1,以40TB的本机写入量、32GB容量来算Intel的SSD写入次数只有1500次,低于闪存通常3000-5000次的写入寿命,而传统技术的SSD写入循环是7万5千次,已经大大超出MLC的写入次数,即便是SLC也难以承受。

上面只是一个例子,降低写入放大率可以延长SSD的使用寿命,提升产品可靠性。至于如何降低WAF就要靠厂商的主控、OP空间、TRIM、GC等技术的处理能力了,通常情况下如果写入数据是不可压缩的,那么WAF不可能小于1,但是SandForce主控支持数据压缩,其WAF通常只有0.5,最新的SF-2281甚至只有0.14,当然这又涉及另一个问题了,数据压缩也不是万能的,如果能像Intel那样做到1.1的放大率就非常好了。