2.2 SSD
SSD是采用非易失性存储芯片的存储盘。当前SSD中主要采用闪存(Flash Memory),也可以采用PCM(Phase Change Memory,相变存储器)等其他非易失性存储芯片。
闪存是一种EEPROM(Electrically-Erasable Programmable Read Only Memory,电可擦编程只读存储器)。闪存自1984年由日本东芝公司提出,至2005年后逐步受到关注。闪存包含NOR(或非型)闪存和NAND(与非型)闪存两种,NAND闪存使用较为广泛。若无特殊说明,本书中提及的闪存均指NAND闪存。
SSD由控制器、闪存(NAND Flash)、DRAM、电源、备电电容、连接器及固件等组成,其结构如图2.8所示。连接器是SSD与主机交互的物理接口。控制器负责在前端提供SATA(Serial Advanced Technology Attachment Interface,串行先进技术总线附属接口)、SAS(Serial Attached Small Computer System Interface,串行小型计算机系统接口)、PCI-e(Peripheral Component Interconnect express,快速外设部件互连)接口或NVMe协议模块与主机交互,进行协议解析和数据传递,内部负责数据的组装和状态管理,后端提供多通道挂接多个闪存,负责对闪存的数据存取、可靠性管理等,同时作为DRAM控制器提供缓存读写接口。电源部分负责把主机提供的电源转换为SSD内部器件工作所需要的各种不同电压值的电源,同时和备电电容配合提供掉电时的备电功能;一般企业级SSD才具有备电电容,消费级SSD不提供备电电容,因此不具备异常掉电保护功能。固件负责管控整盘资源,前端按照协议完成和主机的交互,内部通过闪存转换的地址映射、垃圾回收、磨损均衡等模块实现对闪存的管理,同时通过温度监控、电压监控等实现可靠性相关功能。闪存是SSD的主要存储器件。
图2.8 SSD的结构
2.2.1 闪存单元与结构
闪存单元与传统CMOS(Complementary Metal Oxide Semiconductor,互补金属氧化物半导体器件)单元相比,增加了一层浮栅(Floating Gate),如图2.9所示。浮栅与衬底(Subtrate)之间有一层氧化物绝缘层,称为隧穿层。闪存单元通过施加电压将电子充入浮栅。由于隧穿层的存在,电子不容易逃逸,因为浮栅可以较为稳定地保持电子的状态,从而表示闪存单元的状态。
图2.9 闪存单元的结构[2]
闪存单元通过感应和改变浮栅中电荷的多少对数据进行读写。写入数据时向浮栅注入电荷形成电荷势阱,以表示数据“0”;浮栅中未注入电荷表示数据“1”。读数据时通过感知位线上的电平高低来识别“0”和“1”。
闪存单元可根据每个存储单元存储比特的多少分类,包括SLC(Single Level Cell,单级单元)、MLC(Multi Level Cell,多级单元)、TLC(Triple Level Cell,三级单元)和QLC(Quad Level Cell,四级单元)等,如图2.10所示。SLC表示一个存储单元只存储1比特。这时候只需要区分浮栅上是否存有一定量的电荷即可。MLC表示一个单元存储2比特。这时候不但要区分该单元是否存储了电荷,还需要判断其存储了多少电荷,且需要控制对浮栅编程的电荷数量。TLC表示一个存储单元存储3比特。QLC表示一个存储单元存储4比特。以TLC模式举例,将TLC存储的比特,分为Lower Bit、Upper Bit和Extra Bit,读取Lower Bit需要一个读电压即可,读取Upper Bit和Extra Bit则需要多个读电压。
图2.10 闪存多比特单元[2]
闪存具有如下特性。
写前擦除:在闪存中,闪存单元的编程为单向编程,即仅支持从状态“1”写为状态“0”,而不支持从状态“0”写为状态“1”。闪存在重写一个页前,需要进行擦除操作。闪存以页为单位读写,以块为单位擦除。
读写粒度与擦除粒度不同:闪存的读、写及擦除操作的延迟差异较大。单个闪存页的读平均延迟为十微秒量级,写平均延迟为百微秒量级,而擦除的平均延迟在毫秒量级。
磨损问题:闪存单元具有有限次的P/E(Programming/Erase,擦/写)操作,即每个闪存单元具有有限的寿命。闪存单元在接近擦写次数极限时,无法可靠存储数据状态。这被称为闪存的耐久性(Endurance)问题。尽管存储密度得以提升,单位容量价格降低,但闪存的耐久性问题却愈加严峻。每个SLC闪存单元可承受100000次P/E操作,每个MLC闪存单元可承受10000次P/E操作,而每个TLC闪存单元可承受的P/E操作次数仅为1000次。
为避免P/E操作引入的延迟,闪存采用异地更新的策略进行页重写,即将新的页重定向到空闲闪存页,并标记当前页为无效页,以进行后续回收。
在SSD内部,闪存芯片通过不同的通道连接到闪存控制器,如图2.11所示。在闪存芯片中,单个芯片封装了多个颗粒,每个颗粒可独立执行指令。每个颗粒包含多个闪存片,每个闪存片拥有独立的寄存器,可提供多闪存片之间的流水指令执行。
注:FTL即Flash Translation Layer,闪存转换层。
图2.11 SSD内部结构示意
NAND芯片内部结构如图2.12所示,该图展示了一个Target的结构。一个封装的NAND芯片内部可能包含多个Target,每个Target都由一个独立的片选信号CE#控制,每个Target可能包含多个LUN(Logic Unit Number,逻辑单元号)/芯片(Die),通常为1个、2个、4个或8个等,LUN是执行指令的最小单元,不同的LUN可以并行地执行指令。每个LUN内,可以被划分为一个或者多个平面,每个平面对应一组闪存块和一个缓存。闪存块是执行P/E操作的最小单位,由若干个WL(Word Line,字线)控制的存储单元组成。页(Page)是执行读/写操作的最小单位,对于TLC而言,一个WL对应3个页,包括数据部分和冗余部分(带外数据)。除了不同LUN之间可以并行执行指令外,同一个LUN内部的不同平面也可以并行执行一些操作。
图2.12 NAND芯片内部结构
通过不同级别的并发,SSD可提供充足的访问带宽。这一特性被称为SSD的内部并发特性。表2.1给出了SSD与磁盘的性能比较。
表2.1 SSD与磁盘的性能比较[3]
2.2.2 FTL
SSD采用FTL对闪存的读、写、擦操作进行管理,并向软件系统提供读写接口。FTL主要包含地址映射、垃圾回收和磨损均衡等功能。除此之外,SSD内还需要支持ECC(Error Correction Code,纠错码)纠错、坏块管理等功能。
1.地址映射
地址映射记录了SSD逻辑地址与闪存物理地址的映射关系,支持闪存异地更新。地址映射有页级地址映射、块级地址映射和混合地址映射3种。
(1)页级地址映射
页级地址映射以闪存页为粒度进行重映射。页级地址映射避免了闪存块合并过程中的页复制,但需要较大的映射表。
页级地址映射即为每个LPN(Logical Page Number,逻辑页号)创建一个表项映射到SSD的PPN(Physical Page Number,物理页号)上,如图2.13所示,页级地址映射的优势在于每个LPN都可以映射到任意一个PPN上。但是映射表开销非常大,这种映射方式映射表的大小为SSD总容量/单个PPN大小×每条映射的大小。由于每个闪存页通常为4 KB,一条映射也需要几字节来存放,页级地址映射的映射表通常占闪存总容量的千分之一。
图2.13 页级地址映射
(2)块级地址映射
块级地址映射以闪存块为粒度进行重映射。其优势在于映射表较小,但需要维护闪存块内数据的顺序,因而需要进行闪存块合并,引发许多不必要的页复制。
由于以块粒度进行映射,在进行地址转换时需要将逻辑地址分为LBN(Logical Block Number,逻辑块号)和块内偏移两部分,LBN通过FTL表项转换为PBN(Physical Block Number,物理块号),然后拼接块内偏移得到物理页级地址,如图2.14所示。对于LBN相同的页来说,它们一定在同一个物理块上,这就导致了在映射发生改变时可能需要移动大量的页。块级别的地址映射有效减少了映射表大小。
图2.14 块级地址映射
(3)混合地址映射
混合地址映射则是页级地址映射和块级地址映射的折中方式。
混合地址映射有不同的混合方式。通常,混合地址映射用页级地址映射存储新的数据或热数据,用块级地址映射存储旧的数据或冷数据。
数据的更新操作会先以日志的形式写入日志块,当日志块用完时,会合并这些块中的有效数据,然后写入数据块,对于部分文件的频繁读写,日志块的设计减少了擦除的次数,降低了擦除开销。而混合的映射机制有效降低了映射表的大小,如图2.15所示。
图2.15 混合地址映射
2.垃圾回收
垃圾回收负责选择并擦除失效的闪存页,以恢复空闲状态,等待新数据写入。垃圾回收可以以前台与后台两种方式运行。前台运行的垃圾回收是指SSD的空闲空间低于设定阈值,从而引发的强制垃圾回收方式。后台运行的垃圾回收是指垃圾回收线程周期性启动以擦除无效闪存块的方式。这两种方式可同时在单个FTL中实现。在垃圾回收过程中,FTL首先需要选择合适的待擦除闪存块(Victim Block),然后将其中的有效页复制至其他闪存块的空闲页中,最后擦除该闪存块。有效页的移动将带来SSD内部的额外写入,这既引入额外延迟,影响闪存性能,也增加闪存磨损次数,降低闪存寿命。这也被称为SSD的写放大(Write Amplification)问题。因此,垃圾回收在选择待擦除闪存块时尽可能选择有效页面较少的闪存块。
闪存以块粒度进行擦除,但实际进行垃圾回收时的开销不止一个块擦除的开销。闪存以页粒度进行读写,并且需要在擦除一个页后才能进行下一次写操作,由于同一个块内不同页的读写情况并不完全一致,一个块上可能同时存在有效页和无效页,因此在擦除时需要考虑将有效页移动到其他块,再进行擦除。因此,垃圾回收的开销是有效页移动的开销加上块擦除的开销。
3.磨损均衡
由于闪存具有耐久性问题,为保证SSD中数据的可靠存储,SSD将其中擦写次数达到设定值的闪存页标记为失效。SSD的寿命是该设备能够提供足够可用空间的时间。为了延长SSD的寿命,FTL采用磨损均衡策略将擦写操作尽可能均衡到所有的闪存页。磨损均衡策略包括静态和动态两种。静态磨损均衡选择所有闪存块(包括空闲闪存块和已使用闪存块)中擦写次数较少的闪存块进行空间分配和数据写入。而动态磨损均衡仅从空闲闪存块中选择擦写次数较少的闪存块进行空间分配和数据写入。
4.ECC
BCH算法以发明它的3位数学家的名字命名,这3位数学家分别为玻色(Bose)、雷-乔杜里(Ray-Chaudhuri)和霍昆海姆(Hocquenghem)。在数据写入过程中,BCH 算法利用一个代数公式对原始数据进行顺序循环编码并存储在NAND介质中。在数据读取过程中,BCH算法利用数学原理进行循环计算读取数据,并判断其正确性和可纠正的错误。BCH算法的核心是利用原始数据建立多项式码字,并且计算生成冗余数据,冗余数据与编码数据之间建立和为0的严密校验关系,当编码数据出现少量错误时,则可通过解多项式的计算方式恢复错误数据。
LDPC本质是一种线性纠错编码,可以实现编解码时间与码长的线性化,并利用稀疏矩阵迭代运算进行信息冗余和纠错。LDPC算法相对于以往的信息编码算法,突出特点是引入了硬判决和软判决机制。LDPC硬判决过程利用单次读电压获取NAND介质的“0”或“1”的可能性,并实现数据线性译码。而LDPC软判决接收到的信息是LLR(Log-Likelihood Ratio,对数似然比)序列,LLR序列是一串实数序列,每一个实数代表该比特是“0”或“1”的概率值。正数代表该比特是“0”的概率值,其值越大则是“0”的可能性越大。负数代表该比特数是“1”的概率值,其绝对值越大则是“1”的可能性越大。LDPC译码器利用这一串LLR序列,将LLR序列中大于等于0的位置记为0,将小于0的位置记为1,得到一串0/1的序列,然后乘以校验矩阵,若全为零,则得到正确码字,退出迭代,否则继续迭代,直到迭代出正确码字或者达到最大迭代次数为止。LDPC软判决通过动态调整NAND介质内部读取电压值的量化分级获得0或1的多种可能的值,从而尽可能利用信道的有效软信息。多次软判决可有效改善编码信噪比增益,从而提高LDPC算法的解码成功率。基于NAND闪存介质的LDPC算法则可提高对介质错误的容忍,从而改善SSD的可靠性。