SSD 页、块、垃圾回收

基本操作:

读出、写入、擦除:

因为NAND闪存单元的组织结构限制,单独读写一个闪存单元是不可能的。存储单元被组织起来并有着十分特别的属性。要知道这些属性对于为固态硬盘优化数据结构的过程和理解其行为来说是很重要的。我 在下方描述了关于读写擦除操作的SSD的基本属性

读是以页大小对齐的

一次读取少于一页的内容是不可能的。操作系统当然可以只请求一字节,但是SSD会访问整个页,强制读取远超所需的数据。

写是以页大小对齐的

将数据写入SSD的时候,写入的增量也是页大小。因此即使一个写入操作只影响到一个字节,无论如何整个页都会写入。写入比所需更多的数据的行为被称为写入放大,其概念在3.3节。另外,向某页写入的行为有时候被称为“编置(to program)”一页,因此在大多数关于SSD的出版物和文章中“write 写”和“program编置”是可以互相替换的

页不能被复写

NAND闪存页只有在其“空闲”着的时候才能写入。当数据改变后,这页的内容被拷贝到一个内部寄存器,此时数据更新而新版本的数据存储在一个“空闲”的页中,这被称为“读-改-写”操作。数据并非就地更新,因为“空闲”页与原来存储数据的页不是同一个页。一旦数据被硬盘保存,原先的页被标记为“stale(意为 腐败的 不新鲜的)”,直到其被擦除。

擦除以块对齐

页不能被复写,而一旦其成为stale,让其重新空闲下来的唯一方法是擦除他们。但是对单个页进行擦除是不可能的,只能一次擦除整个块。在用户看来,访问数据的时候只有读和写命令。擦除命令则是当SSD控制器需要回收stale页来获取空闲空间的时候,由其垃圾回收进程触发。

写入的例子:

下边的图是向SSD写入的一个例子。只显示了两个块,每个块有4个页。显然这是一个为了简化我在这使用的例子而精简的NAND闪存封装示意。图中的每一步里,图右侧的圆点解释了发生的事情。

写入放大:

因为写入是按页大小对齐的,任何没有对齐一个或者多个页大小的写操作都会写入大于所需的数据,这是写入放大的概念[13]。写一个字节最终导致一整页都要写入,而一页的大小在某些型号的SSD中可能达到16KB,这是相当没有效率的。

而这不是唯一的问题。除了写入过多的数据外,这些额外的写入也会触发更多不必要的内部操作。实际上,用未对齐的方法写入数据会导致在更改和写回硬盘之前需要页读到缓存,这比直接写入硬盘要慢。这个操作被称为读-改-写,且应该尽可能的避免[2, 5]

绝不进行少于一页的写入

避免写入小于NAND闪存页大小的数据块来最小化写入放大和读-改-写操作。现在一页的大小最大的是16KB,因此这个值应作为缺省值使用。闪存页大小的值基于SSD型号并且在未来SSD发展中可能会增加。

对齐写入

以页大小对齐写入,并写入大小为数个页大小的数据块。

缓存化小写入

为了最大化吞吐量,尽可能的将小数据写入RAM缓存中,当缓存满了之后执行一个大的写入来合并所有的小写入。

损耗均衡

如我们在1.1节讨论的那样,NAND闪存单元因其有P/E循环限制导致其有生命限制。想象一下我们有一个SSD,数据总是在同一个块上写入。这个块将很快达到其P/E循环限制、耗尽。而SSD控制器井标记其为不可用。这样硬盘的容量将减小。想象一下买了一个500GB的硬盘,过了几年还剩250G,这会非常恼火。

因此,SSD控制器的一个主要目标是实现损耗均衡,即是将P/E循环在块间尽可能的平均分配。理想上,所有的块会在同一时间达到P/E循环上限并耗尽。[12, 14]

为了达到最好的全局损耗均衡,SSD控制器需要明智的选择要写入的块,且可能需要在数个块之间移动,其内部的进程会导致写入放大的增加。因此,块的管理是在最大化损耗均衡和最小话写入放大之间的权衡。

制造商想出各种各样的功能来实现损耗均衡,例如下一节要讲的垃圾回收。

因为NAND闪存单元会耗尽,FTL的一个主要目标是尽可能平均的将工作分配给各个闪存单元,这样使得各个块将会在同一时间达到他们的P/E循环限制而耗尽。

垃圾回收

页不能被复写。如果页中的数据必须更新,新版本必须写到空页中,而保存之前版本数据的页被标记为stale。当块被stale页充满后,其需要在能够再写入之前进行擦除。

SSD控制器中的垃圾回收进程确保“stale”的页被擦除并变为“free”状态,使得进来的写入命令可以访问这个页。

如第一节中所说,擦除命令需要1500-3500 μs,写入命令需要250-1500 μs。因为擦除比写入需要更高的延迟,额外的擦除步骤导致一个延迟使得写入更慢。因此,一些控制器实现了后台垃圾回收进程,或者被称为闲置垃圾回收,其充分利用空闲时间并经常在后台运行以回收stale页并确保将来的前台操作具有不足够的空页来实现最高性能[1]。其他的实现使用并行垃圾回收方法,其在来自主机的写入操作的同时,以并行方式进行垃圾回收操作。

遇到写入工作负载重到垃圾回收需要在主机来了命令之后实时运行的情况并非罕见。在这种情况下,本应运行在后台的垃圾回收进程可能会干预到前台命令[1]。TRIM命令和预留空间是减少这种影响的很好的方法,具体细节将在6.1和6.2节介绍。

后台操作可能影响前台操作

诸如垃圾回收后台操作可能会对来自主机的前台操作造成负面影响,尤其是在持续的小随机写入的工作负载下。

块需要移动的一个不太重要的原因是read disturb(读取扰乱)。读取可能改变临近单元的状态,因此需要再一定数量的读取之后移动块数据[14]

数据改变率是一个很重要的影响因素。有些数据很少变化,称为冷数据或者静态数据,而其他一些数据更新的很频繁,称为热数据或者动态数据。如果一个页一部分储存冷数据,另一部分储存热数据,这样冷数据会随着热数据一起在垃圾回收以损耗均衡的过程中拷贝,冷数据的存在增加了写入放大。这可以通过将冷数据从热数据之中分离出来,存储到另外的页中来避免。缺点是这样会使保存冷数据的页更少擦除,因此必须将保存冷数据和热数据的块经常交换以确保损耗均衡。

因为数据的热度是在应用级确定的,FTL没法知道一个页中有多少冷数据和热数据。改进SSD性能的一个办法是尽可能将冷热数据分到不同的页中,使垃圾回收的工作更简单。

分开冷热数据

热数据是经常改变的数据,而冷数据是不经常改变的数据。如果一些热数据和冷数据一起保存到同一个页中,冷数据会随着热数据的读-改-写操作一起复制很多次,并在为了损耗均衡进行垃圾回收过程中一起移动。尽可能的将冷热数据分到不同的页中是垃圾回收的工作更简单

缓存热数据

极其热的数据应该尽可能多的缓存,并尽可能的少的写入到硬盘中。

以较大的量废除旧数据

当一些数据不再需要或者需要删除的时候,最好等其它的数据一起,在一个操作中废除一大批数据。这会使垃圾回收进程一次处理更大的区域而最小化内部碎片。

reference: http://codecapsule.com/2014/02/12/ 

posted @ 2018-12-26 10:54  penghan  阅读(3013)  评论(0编辑  收藏  举报