在上期,我们讲到,SSD的擦除,是以块(block)为单位进行的,每次将擦除若干个页(page)的内容。如果我们需要改写一个页(page),有两种实现方法:
第一种实现方法是,读出这个页所在的块所有的内容到内存缓冲区,在内存缓冲区中改写这个页,然后将这个块的内容写入SSD盘。也就是会面对写放大的问题;
如图,SSD的组织方式为Block-Page-Byte三级:
假设要改写这里:
先将整个Block读入到内存缓冲区,擦除整个Block:
然后写入整个Block:
用生活中的例子类比,可以类比为已经打印好的标书中有一个错别字,将这页重新打印替换原来的错误页。
另一种方式实现方法是,如果SSD盘上还有未被写过的页(也就是内容为全1的页),那么在将要改写的内容写到未被分配的页,并让SSD控制器重新将该页的LBA(Logic Block Address)映射到新写入的页。
如图:
同时,为了使得删除了部分数据的SSD盘,能够把多个分散的空闲页合并为空闲块,SSD控制器会定期扫描全盘,做数据搬移和归并动作;(类似机械硬盘的硬盘碎片整理)
如图:
空闲块散落在各个Block。
SSD控制器将这些空闲块收集起来,进行“关停并转”:
为什么要对空闲块进行收集呢?
原来,操作系统在删除文件的时候,并不真的擦除文件所在的存储空间的内容,而是在文件系统的索引上做一个删除标记。如DOS系统仅仅是把目录中文件名的第一个字符改成“#”符号而已。这样,在SSD中,这个page虽然被标记为数据已删除,但内容并未被擦除,也就是并非全1,是不可以对内写入的。
因此,SSD控制器引入了垃圾收集(GC)机制,采用一定的算法,在后台搬运数据,以腾挪出整个空闲的block来,进行擦除后设定为可分配状态,尽量增加空闲的block和page,以避免写放大的发生,提升写入性能。
我们知道,SSD盘的最常见应用场景就是数据库。以MySQL为例,每次数据库写入(Transcation),除了写入数据行的对应字段外,还涉及对B+树的改写。因此,如果期望MySQL数据库的写性能达到3万TPS,其磁盘随机IO性能就需要达到20万IOPS以上。实际上,在NVMe SSD中,单盘的随机写性能峰值可达50万IOPS。
我们注意到,由于写入是随机的,如果我们期望每次写入都能够直接写空闲page,而不产生写放大,那么,就需要SSD控制器迅速地完成GC工作。但是,如果SSD控制器需要每秒产生50万个空闲块,也就是需要在2000ns内完成一个空闲块的搬运,这实际上也是非常困难的。
因此,工程师们想到了,让控制器在写入的时候,利用预留的空闲空间——OP空间。
OP是Over Provisioning的缩写。它是干什么用的呢?
我们回忆一下上期学过的:
SSD的存储单元由特殊工艺制作的浮栅场效应管构成。这个东西是有寿命的。如开启次数较多后,其电阻会下降,导致存储单元缓慢漏电。对于SLC SSD,只要漏电后的电压差不达到1/2的工作电压,就不影响数据的读出,而对于TLC和QLC SSD,要求漏电后的电压差在1/8和1/16工作电压范围内。因此,QLC的寿命最短,而SLC的寿命最长。
SSD有另一个重要的指标:DWPD(Drive Writes Per Day)。这个指标指的是在预期寿命内可每日完整写入SSD固态硬盘所有容量的次数。举一个例子:
某块SSD盘容量为6.4TB,其DWPD为3 DWPD*5年,指的是5年内,可以每天把全盘的容量写入3次,也就是每天写入19.2TB的数据。那么,在5年中,每个浮栅场效应管需要承受(365*5+2)*3 (考虑到5年中必然有2个闰年)=5481次写入。
而SSD存储单元(浮栅场效应管)的寿命服从泊松分布,也就是写入的次数越多,其故障概率越高。那么,如果某一个Page出现了一个浮栅场效应管损坏,是不是这个Page都标注为损坏呢?
如果这么做,那么SSD的寿命就太短了。实际上,SSD的设计者会在每个Page内预留一部分存储单元,有少量存储单元损坏的时候,预留的存储单元可以代替其功能。
类似地,在整颗芯片中,也有一定的预留空间,这就是所谓的OP空间。OP空间可以用来顶替损坏的块,从而实现SSD盘的寿命延长。
那么,OP空间是如何用于提升SSD盘的读写性能的呢?
请看下期分解。