SSD目前几乎是商用的普通服务器上标配,因此,作为软件开发人员,也需要了解的SSD基本原理,以便开发时能更好的发挥其优势,规避其劣势。本文总结了作为软件开发人员需要了解的SSD基本原理,全文组织结构如下:
首先,从软件开发人员作为SSD的用户角度来讲,首先需要了解的是SSD和普通HDD的性能对比,如下:
先来看顺序读和顺序写
其中,Seagate ST3000DM001是HDD,其他的都是SSD。从上述两图中可以看出,HDD的顺序读速度差不多为最慢的SSD的一半,顺序写稍微好点,但也比大部分慢一倍左右的速度。
再来看随机读和随机写
可以看出,HDD的随机读的性能是普通SSD的几十分之一,随机写性能更差。
因此,可以看出SSD的随机读和写性能要远远好于HDD,本文接下来的几个小节将会讨论为什么SSD的随机读写性能要远远高于HDD?
备注:本小节测试数据全部来自于 HDD VS SSD 。
SSD内部一般使用NAND闪存来作为存储介质,其逻辑结构如下:
SSD中一般有多个NAND Flash,每个NAND Flash包含多个Block,每个Block包含多个Page。由于NAND的特性,其存取都必须以page为单位,即每次读写至少是一个page,通常地,每个page为4k或者8k大小。另外,NAND还有一个特性是,其只能是读或写单个page,但不能覆盖写如某个page,必须先要清空里面的内容,再写入。由于清空内容的电压较高,必须是以block为单位。因此,没有空闲的page时,必须要找到没有有效内容的block,先擦写,然后再选择空闲的page写入。
在SSD中,一般会维护一个mapping table,维护逻辑地址到物理地址的映射。每次读写时,可以通过逻辑地址直接查表计算出物理地址,与传统的机械磁盘相比,省去了寻道时间和旋转时间。
从NAND Flash的原理可以看出,其和HDD的主要区别为
对于SSD,其读流程主要包括两方面:
对于HDD,其读流程也是两块:
因此,在顺序读测试中,由于定位数据只需要一次,定位之后,后面就是大批量的读取数据的过程,此时,HDD和SSD的性能差距主要体现在读取速度上,HDD能到200M左右,而普通SSD是其两倍。
在随机读测试中,由于每次读都要先定位数据,然后再读取,HDD的定位数据的耗费时间很多,一般是几毫秒到十几毫秒,远远高于SSD的定位数据时间(一般0.1ms左右),因此,随机读写测试主要体现在两者的定位数据的速度上,此时,SSD的性能是要远远好于HDD的。
对于SSD的写流程,取决于不同的情况,有不同的处理流程,主要是受到NAND Flash的如下特性限制
SSD的写分为新写入和更新两种,处理流程不同。
先看新写入的数据的流程,如下:
假设新写入了一个page,其流程如下:
而更新操作的流程如下:
假设是更新了page G中的某些字节,流程如下:
可以看出,如果在更新操作比较多的情况下,会产生较多的无效页,类似于磁盘碎片,此时,需要SSD的over-provisioning和garbage-collection。
over-provisioning是指SSD实际的存储空间比可写入的空间要大,比如,一块可用容量为120G的SSD,实际空间可能有128G。为什么需要over-provisioning呢?请看如下例子:
如上图所示,假设系统中就两个block,最终还剩下两个无效的page,此时,要写入一个新page,根据NAND原理,必须要先对两个无效的page擦除才能用于写入。此时,就需要用到SSD提供的额外空间,才能用garbage-collection方法整理出可用空间。
garbage collection的整理流程如上图所示
有空闲块之后,就可以按照正常的流程来写入了。
SSD的garbage-collection会带来两个问题:
如果频繁的在某些块上做garbage-collection,那么这些原件就容易比其他部分更快到达擦写次数限制,因此,需要某个算法,能使得原件的擦写次数比较平均,这样才能使得SSD的寿命延长,这就需要下面要讨论的损耗均衡控制了。
为了避免某些block被频繁的更新,而另外一些block则非常的空闲,SSD控制器一般会记录各个block的写入次数,并且通过一定的算法,来达到每个block的写入都比较均衡。
以一个例子,说明损耗均衡控制的重要性:
假如一个NAND Flash总共有4096个block,每个block的擦写次数最大为10000。其中有三个文件,每个文件占用50个block,平均10分钟更新一个文件,假设没有均衡控制,那么只会3 * 50 + 50共200个block,则这个SSD的寿命如下:
大约为278天。而如果假设是完美的损耗均衡控制,即4096个block都均衡的参与更新,则使用寿命如下:
大约5689天。因此,设计一个好的损耗均衡控制算法是非常有必要的,主要有两种:
这里的dynamic和static是指的是数据的特性,如果数据频繁的更新,那么数据是dynamic的,如果数据写入后,不更新,那么是static的。
dynamic wear leveling的原理是记录每个block的擦写次数,每次写入数据时,找到被擦除次数最小的空block。
static wear leveling的原理分为两块:
以一个例子来说明,两种擦写算法的不同点:
假如SSD中有25%的数据是dynamic的,另外75%的数据是static的。对于dynamic wear leveling方法,每次要找的是擦除了数据的block,而static的block里面是有数据的,因此,每次都只会在dynamic的block中,即最多会在25%的block中做均衡;对于static算法,每次找的block既可能是dynamic的,也可能是static的,因此,最多有可能在全部的block中做均衡。
相对而言,static算法能使得SSD的寿命更长,但也有其缺点:
最后,我们分析一下SSD的写放大问题,一般由如下三个方面引起:
通常的,需要在其他方面和SSD的写放大之间做权衡,例如,可以减少garbage collection的频率来减少写放大问题;可以把SSD分成多个zone,每个zone使用不同的wear leveling方法等等。
个人理解,使用SSD时,我们需要考虑如下情况: