Write Amplification 写入放大,Write Amplification Factor写入放大系数。写放大系数的含义:当我们的host要求向ssd写入A大小的有效资料,而实际上由于flash的特性,我们真正写入flash的资料大小是B,那么B/A就是写放大系数。

Cause

WA写入放大的元凶是GC垃圾回收。当操作系统当删除一个数据时,数据不会立马删除,而是把这个要删除的数据上标记一个“删”的标签,此时实际上没有真正删除[这也是硬盘上数据再删除之后仍存在机会恢复的原因]。

WA只存在与闪存中,机械硬盘不存在这个问题。因为SSD的设计完全不同于传统的机械磁盘,而两者的工作原理也不同,SSD一个完整的电子设备,没有传统机械盘的读写磁头。因此,在读写数据的时候由于少了磁头在磁道之间的寻道过程所以SSD能提供较高的IOPS性能。也正因为其少了磁头的调度,所以SSD还能减少电量的使用[磁头移动也耗电]。但是SSD也存在一些问题,写入在SSD中的数据是不可以直接更新的,只能通过扇区覆盖重写,在覆盖重写之前需要先擦除,而且擦除操作又是不能在扇区上做的,只能在磁盘的块上来完成,擦除块之前需要将原有的还有效的数据先读出,然后在与新来的数据一起写入,这些重复的操作不单会增加写入的数据量,还会减少闪存的寿命,更吃光闪存的可用带宽而间接影响随机写入性能。具体说来,当机械硬盘要写入新数据时可以直接覆盖那些已经被标记“删”标签的数据,而固态硬盘不行,只能先擦除旧的数据才能写入新数据,而NAND闪存工作原理是以4K页(page)为一个单元写入的,但擦除只能以块block[64个page]为单位,如果一个块block上有32个page有效数据和32个被标记“删”标签的无效数据,那要在这个块block上重新写入数据,那必须要擦除整个块block,那还有一半有效数据怎么办了?那只有把那32page的有效数据就要搬到另一个有空位置的块block中,这个这就是GC垃圾回收技术,把有效的数据搬到另一个块block中,原本就已经写入过一次了再加上这次搬迁不就又多了一次写入吗,这就是所谓的写入放大。这也就是为什么在磁盘写满后,如果老化掉一些最久未使用的数据块后,继续大量写入新的数据,随着时间的推移,写入速度变得比刚开始时慢了许多

举个最简单的例子:当要写入一个4KB的数据时,最坏的情况是一个块里已经没有干净空间了,但有无效的数据可以擦除,所以主控就把所有的数据读到缓存,擦除块,缓存里更新整个块的数据,再把新数据写回去,这个操作带来的写入放大就是: 实际写4K的数据,造成了整个块(共512KB)的写入操作,那就是放大了128倍。同时还带来了原本只需要简单一步写入4KB的操作变成:闪存读取(512KB)→缓存改(4KB)→闪存擦除(512KB)→闪存写入(512KB),共四步操作,造成延迟大大增加,速度变慢。所以说WA是影响SSD随机写入性能和寿命的关键因素。

闪存的编程和擦除次数有限。通常以闪存在整个寿命中最多可忍受的编程/擦除循环(P/E循环)次数来表示。写入放大越低,则越为理想,因为与之对应的是闪存中P/E循环次数减少,所以能延长SSD的寿命。

Solution

在实际操作中我们很难完全解决掉SSD写入放大的问题,只能通过某些方法来更有效的减少放大的倍数。一个很简单的办法就是将一块大的SSD硬盘只使用其的一部分容量,比如128GB你只是用64GB,当然这种方法有点过于浪费资源了。现阶段公认的比较好的方法是TRIM。TRIM位于操作系统层。操作系统使用TRIM命令来通知SSD某个page的数据不需要了,则可以回收。支持TRIM的操作系统和以往的主要区别是删除一个Page的操作不同。在磁盘时期,删除一个page之后在文件系统的记录信息里将该page的标志位设置为可用,但是并没有将数据删除。使用SSD且支持TRIM的操作系统,在删除一个page时,会同时通知SSD这个page的数据不需要了,SSD内部有一个空闲时刻的垃圾收集进程,在空闲时刻SSD会将一些空闲的数据集中到一起,然后一起Erase。这样每次写操作,就在已经Erase好了的Page上写入新的数据

另一个基于hardward的机制是提供一个裸的SSD,然后允许用户自定义很多操作,通过用户自己的设计机制来尽量避免WA,比如目前的Open-Channel SSD就是一例。