【www.hj8828.com】统一准备 SSD(机械硬盘)友好的主次

SSD为存储系统提供了难以置信的性能,它的性能比最快的机械硬盘还高出10倍。然而由于SSD的写性能会受到块擦除延时的影响,所以SSD通常作为读取设备。但这并不是说SSD对写性能没有提升,其实它会提升写性能,只是SSD的写性能只有读性能的一半。另外,SSD的写性能是逐渐下降的,这也是它的一个性能问题。

前言

为了提升我们的软件性能,我们有多种方法,如合理的数据结构、优秀的算法,还有非常重要的一点就是:依据软件所依附的硬件自身特性,设计能最大限度发挥硬件性能的软件。根据计算机内存快但无法持久化,硬盘可以持久化但是慢的特性,我们设计了「缓存」这一策略来提升性能;根据硬盘随机读写慢但顺序读写快这一特性,Kafka
用自己独特的方式来实现高吞吐量的队列。如今,由于 SSD
出色的性能以及逐渐降低的价格,有逐步代替
HDD(传统硬盘)的趋势,而我们之前的大部分程序是基于 HDD
开发的,并不能最好的发挥 SSD 的性能,因此,我们有必要了解 SSD
的特性,以及如何写更适合于 SSD 的程序。

NOR和NAND是现在市场上两种主要的非易失闪存技术。flash按照内部存储结构不同,分为两种:nor flash和nand flash。

SSD技术限定了写操作的生命周期(读操作不会影响SSD产品的生命周期和可靠性)。SSD芯片使用“单元”来记录数据位。当这些单元被写入、擦除或重新写入时,这些操作都将逐渐降低单元的性能。在经历了一定数量的程序周期/擦除周期后,一个单元将会损坏从而无法再被使用。控制器会记录这些损坏的单元,从而避免这些坏块再被使用,这和它们对传统硬盘坏块所做的一样。单元损坏后,SSD的容量会减小,直到它必须被替换掉。IT管理者为SSD投入了很大的花费,所以他们希望采取一些方法来保证SSD的最大使用寿命。SSD厂商会提供保修服务,有一些厂商甚至会额外提供20%的存储容量来抵消损坏单元所造成的影响。

SSD 介绍

SSD
是用固态电子存储芯片阵列而制成的硬盘,由控制单元和存储单元(FLASH芯片、DRAM芯片)组成。SSD
的每个数据位保存在由浮栅晶体管制成的闪存单元里。SSD整个都是由电子组件制成的,没有像硬盘那样的移动或者机械的部分。SSD
的内部架构如下:

SSD 内部架构

 

SSD在制造上主要有三种技术:多层单元(MLS)、增强型多层单元(eMLC)和单层单元(SLC)。MLC是面向个人消费者的产品,因为它的制造成本和价格都是最低的,理所当然它的使用寿命也是最短的。MLC芯片的写操作为3000-10000次。与MLC相对,企业级SSD通常使用SLC技术,SLC可以支持100000次写操作。另一个选项是eMLC,它同时吸取了MLC和SLC的优点,它支持20000-30000次写操作,但价格却低于SLC。总而言之,你愿意花费多少,你就能得到多少。

1. 使用寿命

SSD
的数据保存在浮栅晶体管中,浮栅晶体管使用电压来实现每个位的读写和擦除。写晶体管有两个方法:NOR
闪存和 NAND 闪存。目前大多数制造商都采用 NAND 闪存,NAND
闪存模块的一个重要特征是,他们的闪存单元是损耗性的,因此它们有一个寿命。衡量寿命的单位是
PE周期(program/erase cycles)

1、Nand Flash

尽管厂商试图通过写缓存和顺序写来减轻这些问题,但如果IT管理者能够聪明的部署SSD,就能够最大程度的得到SSD的使用寿命。以下是一些好的方法:

2. 性能

下图是 SSD 与其他存储介质的性能对比:

SSD 与其他存储介质的性能对比

其中 SLC、MLC、TLC 可以理解为不同类型的 SSD,下面会有介绍。

  在工艺制程方面分NAND
flash有两种类型:MLC和SLC。MLC和SLC属于两种不同类型的NAND FLASH存储器。SLC全称是Single-Level
Cell,即单层单元闪存,而MLC全称则是Multi-Level
Cell,即为多层单元闪存。
      它们之间的区别,在于SLC每一个单元,只能存储一位数据,MLC每一个单元可以存储两位数据,MLC的数据密度要比SLC 大一倍。在页面容量方面分NAND也有两种类型:大页面NAND flash(如:HY27UF082G2B)和小页面NAND flash(如:K9F1G08U0A)。
这两种类型在页面容量,命令序列、地址序列、页内访问、坏块标识方面都有很大的不同,并遵循不同的约定所以在移植驱动时要特别注意。

第1步:了解应用程序的使用数据特征。

2. 存储结构

SSD 存储结构分为单元、页、块三层,下面依次介绍:

  • 单元(cell):单元是 SSD
    存储的最小单位,由于采用的闪存类型不同,各类闪存中的单元能存储的数据也不同,目前有三种闪存单元类型:

    • 单层单元(SLC),这种的晶体管只能存储 1 个比特但寿命很长。
    • 多层单元(MLC),这种的晶体管可以存储 2 个比特,但是会导致增
      加延迟时间和相对于SLC减少寿命。
    • 三层单元(TLC),这种的晶体管可以保存 3
      个比特,但是会有更高的延迟时间和更短的寿命。
  • 页(page):页由许多单元组成,是我们读写 SSD
    的最小单位,大多数硬盘的页大小是 2KB、4KB、8 KB 或 16 KB。当我们读
    SSD 的数据时,最少读取一页(就算我们只需要 1
    字节的数据);当我们写数据时,就算只需要写 1
    字节,也会写一页,因此存在写入放大的问题。页不能被重复写

  • 块(block):块由许多页组成,是数据擦除的最小单元,大多数SSD每个块有128或256个页。这即表示一个块的大小可能在
    256 KB 到 4 MB
    之间。之前我们说过,页不能被重复写,要修改页的数据,必须先将页所在的块擦除,然后再重新写入新值(块中其他叶需要缓存然后再写入)。

 

大部分组织都不了解自己的应用程序使用数据的特征。常见的方法是简单的部署最昂贵的HDD硬盘,并且超额提供给应用程序。这很简单,也能良好的工作,但它却使容量管理效率低下,并且带来了不必要的开支。大部分的存储厂商提供性能监测工具来了解实际的I/O使用情况。系统级的性能特性可能可以良好的划分SSD所占存储的比例来满足性能需求,但它们无法对SSD设备的使用寿命提供任何有用的信息。使用寿命是SSD总体拥有成本(TCO)的一个重要组成部分。通过实验来了解应用程序性能需求是以最低TCO来得到足够性能的唯一途径。

3. 数据更新

由于 SSD
不支持数据覆盖写入,因此对于数据的更新,只能将老的数据标记为过期,在另外一个空闲的地方写入更新后的值。具体操作如下图:

数据更新过程

由上图我们可知,更新一个已有数据的流程如下:

  1. 将老的数据所在的页(PPN=0)标记为过期
  2. 在空闲页(PPN=3)写入新值 x’
  3. 当垃圾回收程序检测到该块(Block
    1000)中存在过期数据(PPN=0),准备将其回收。而数据的擦除是以块为单位的,因此,需要先将
    Block 1000 中有效的数据拷贝到另外一个空闲块(Block 2000),然后再将
    Block 1000 擦除。

2、Nor Flash

第2步:将应用程序以读I/O的密集程度分类。

4. 损耗均衡

由于 SSD
存储单元的擦除次数是有限的,而擦除的最小单位是块,所以需要有一个机制来平衡各块的擦除次数,从而使整个
SSD
的各部分损耗更加均衡,这一机制称为损耗均衡。通过该技术,存储数据会在不同的块之间移动,以避免对同一块的频繁擦除。

  在通信方式上Nor Flash 分为两种类型:CFI Flash和 SPI Flash。

在了解了对指定应用程序的I/O特征需求后,下一步就要将读密集型应用程序和SSD的读取性能关联起来。尽管这些数字看起来很枯燥,但利用它们来做出决定是非常科学的。只有少数应用程序是只读的应用程序,毫无疑问SSD是它们的最好选择。大部分的应用程序是有读写需求的,而这个读写的比例是我们用以分类的标准。读操作比例高的应用更能从SSD得到好处,并且副作用很少。

5. 内部并行

因为物理限制的存在,异步 NAND 闪存 I/O 总线无法提供32-40
MB/s以上的带宽。由于一块 SSD
是由多个存储芯片组成的,因此我们可以通过并行读写多个存储芯片的方式来提升
SSD I/O 的性能。

SSD 内部将不同芯片中的多个块称为一个簇(clustered
block)
,一次数据写入可以并行的写入到簇中的不同块中。如下图中,一次数据写入可以拆封成多个并行写入的任务,写入到黄色虚线框的簇中。

clustered block 并行写入

CFI Flash

但问题来了,并非所有读I/O任务都是相等的(事实上我们在谈论读操作时,输入(O)比输入(I)要多)。I/O分为随机I/O、顺序I/O和递归I/O,性能监测工具无法告诉你它们的类别。随机I/O在SSD能容纳所有数据时不会成为一个问题。顺序I/O不会通过SSD而得到好处,除非所有数据都存放在SSD中。并且顺序I/O的应用通常是批处理的,而且只是偶尔运行。如果这些应用没有大量的突发I/O并且对时间要求不是很严格,将它们放置在SSD中从经济角度来说并不划算。对递归读I/O的应用部署SSD是一条黄金准则,这并不需要人们在做出这个决定之前去做过多的理解。

6. 垃圾回收

上面我们已经讲到,SSD
中的数据是不能被重复写的,必须先擦除然后再写,而擦除的速度非常慢(通常为毫秒级),SSD控制芯片会执行垃圾回收操作,即回收使用过的块,确保后续写操作能够快速分配到可用的块。

  CFI Flash英文全称是common
flash interface,也就是公共闪存接口,是由存储芯片工业界定义的一种获取闪存芯片物理参数和结构参数的操作规程和标准。CFI有许多关于闪存芯片的规定,有利于嵌入式对FLASH的编程。现在的很多NOR FLASH 都支持CFI,但并不是所有的都支持。  

第3步:合理的分配SSD存储。

设计 SSD 友好的程序

针对上述介绍的 SSD 特性,在开发程序时我们可以做一些针对性的设计,以提高
SSD 的性能,还有延长 SSD 的使用寿命。

  CFI接口,相对于串口的SPI来说,也被称为parallel接口,并行接口;另外,CFI接口是JEDEC定义的,所以,有的又成CFI接口为JEDEC接口。所以,可以简单理解为:对于Nor Flash来说,CFI接口=JEDEC接口=Parallel接口 = 并行接口

有了上面的数据和预测,存储管理者需要最大化的使用昂贵而有限的资源。他们需要精确提供性能最好的SSD资源。关键应用并不一定对性能有高要求,所以仅仅因为它们很重要而提供最昂贵的的存储是一种对资源的误用。

1. 对齐写入

SSD
数据写入的最小单元是页,因此,如果我们写入的数据小于页大小,会有两个危害:

  • 空间浪费:如果想再次利用页中的空闲部分,必须擦除所处的整个块
  • 读取效率低:一次读取读到的有效数据少,读相同数据需要更多次读操作

对齐写入指一次数据写入是页大小的整数倍,如果数据不够足,可以先缓冲在内存中,例如
Twitter 的 fatcache 就是凑够了1MB 才会写 SSD。

SPI Flash

第4步:不要把成本看得比业务价值还重要。

2. 相关的数据一起写

相关的数据一起写指的是对于经常被一起访问的数据,写的时候尽量一次同时写入,这样做有两个层面的好处:

  • 由于读写的最小单位是页,相关的数据写在一页上,数据读的时候效率高
  • 由于 SSD
    存在内部并行的特性,一次将大量(簇大小的整数倍)相关的数据同时写入,内部会优化并行写入到各个存储芯片,读的时候也能并行读取,可以提升读的性能

  serial peripheral interface串行外围设备接口,是一种常见的时钟同步串行通信接口。