为SSD编程(4)——高级功能和内部并行

原文 http://codecapsule.com/2014/02/12/coding-for-ssds-part-4-advanced-functionalities-and-internal-parallelism/

在这个部分,我将简要的介绍一些SSD的主要功能,如TRIM和预留空间。我同样会介绍SSD中不同等级的内部并行。

5. 高级功能

5.1 TRIM

让我们假设一个程序向SSD所有的逻辑块地址都写入文件,这个SSD当然会被装满。然后删除这些文件。文件系统会报告所有的地方都是空的,尽管硬盘实际上还是满的,因为SSD主控没法知道逻辑数据是什么时候被主机删掉的。SSD主控只会在这些逻辑块地址被复写的时候才知道这些是空闲空间。此时,垃圾回收进程将会擦除与这些文件相关的块,为进来的写操作提供空的页。其结果就是,擦除操作并非在知道保存有无用数据之后立刻执行,而是被延迟了,这将严重影响性能。

另一个值得关心的是,既然SDD主控不知道这些页保存有已删除的文件,垃圾回收机制仍然会为了损耗均衡而移动这些页上的数据。这增加了写入放大,并毫无意义地影响了来自主机的前台工作负载。

延迟擦除问题的一个解决方法是TRIM命令,这个命令由操作系统发送,通知SSD控制器逻辑空间中的这些页不会再使用了。有了这个信息,垃圾回收进程就会知道自己不必再移动这些页,并可以在任何需要的时间擦除它们。TRIM命令只会在当SSD、操作系统和文件系统都支持的时候才起作用。

TRIM命令的维基百科页面列出了支持TRIM的操作系统和文件系统[16]。Linux下,ATA
TRIM的支持是在2.6.33版本加入的。尽管ext2和ext3 文件系统不支持TRIM,ext4 和XFS以及其他的一些是支持的。在Mac OS 10.6.8下,HFS+支持TRIM操作。Windows 7则只支持使用SATA接口的SSD的TRIM,使用PCI-Express的则不支持。

现在大部分的硬盘都支持TRIM,确实,允许垃圾回收尽早的工作显著地提升了将来的性能。因此强烈建议使用支持TRIM的SSD,并确保操作系统和文件系统级都启用了TRIM功能。

5.2 预留空间

预留空间只是简单的使物理块比逻辑块多,即为主控保留一定比例的,用户不可见的物理块。大多专业级SSD生产商已经包括了一些预留空间,通常是7~25%[13]。用户可以简单的通过创建比最大物理容量小的逻辑容量分区来创建更多的预留空间。例如,你可以在100G的硬盘上创建一个90G的分区,而把剩下的10G作为预留空间。即使预留空间在操作系统级是不可见的,但SSD主控仍然是可以看见的。生产商提供预留空间的主要原因是为了对付NAND闪存单元固有的兽兽门限制。不可见的预留空间的块将无缝的替换可见空间上的已耗损殆尽的块。

AnandTech有一篇有意思的文章显示出预留空间对SSD寿命和性能的影响[34]。在他们研究的硬盘上,结果显示出仅通过保证25%的预留空间(把所有的预留空间加在一起)就可以使性能极大地提升。在Percona的一篇文章中有另外一个有意思的结果,在他们测试了一块Intel
320 SSD,显示出当硬盘逐渐填满时,写入吞吐量将随之下降[38]

这里是我的实验中发生的事情。垃圾回收是使用空闲时间在后台擦除页上不再使用的数据的。但既然擦除操作比写入操作的延迟更久,或者说擦除要的时间比写入长,在持续的重随机写入工作负载下的SSD将会在垃圾回收有机会擦除之前用尽所有的空块。此时,FTL将不能跟上前台的随机写入工作负载,而垃圾回收进程将必须在写入命令进来的同时擦除块。这就是在基准测试中SSD性能下降的厉害,而SSD显得性能超差的时候,如下图7所示。因此,预留空间可以吸收高吞吐量写入负载,起到缓冲的作用,为垃圾回收跟上写入操作并重新开始擦除无用块留够时间。预留空间需要多少大部分基于SSD使用环境的工作负载,和其需要的承受的写入操作的量。作为参考,持续随机写入的工作负载比较推荐使用大约25%的预留空间[34]。如果工作负载不是很重,大概10~15%估计够大的了。

预留空间对损耗均衡和性能表现是有用的

SSD可以简单地通过格式化时设置比最大物理容量小的逻辑容量来启动预留空间。余下的不被用户所见的空间仍会被SSD主控所用。预留空间帮助损耗均衡机制来对付NAND闪存单元的寿命限制。对于写入不是很重的工作负载,10~15%的预留空间足够了。对于持续的随机写入工作负载,保持25%的预留空间将会提升性能。预留空间将会扮演NAND闪存块的缓冲区的角色,帮助垃圾回收进程吸收写入峰值。

从此,同样可以推导出,预留空间甚至可能为不支持TRIM命令的环境提供更大的性能提升——注意我只是在这进行个假设,我仍然在寻找材料来支持这个观点。假设只有75%的硬盘空间可被操作系统使用,余下的25%留作预留空间。因为SSD控制器可以看见整个硬盘,尽管在某一时刻只有75%的物理NAND闪存被使用,但100%的块都在已使用、已废弃、已擦除三种状态中交替转换。这表示余下的25%物理闪存将可以安全的认为没有保存有数据,因为其并没有被映射到任何逻辑块地址上。因此,即使不支持TRIM,垃圾回收进程也能够提前擦除这些预留空间中块。

5.3 安全擦除

一些SSD主控提供ATA安全擦除功能,其作用是当硬盘处于意料之外的状态时恢复其性能。这个命令擦除所有用户写入的数据并重置FTL映射表,但这显然不能克服P/E循环有限造成的物理限制。尽管其功能上看上去非常有前途,但需要每个生产商争取的实现它。Wei等人2011年在他们关于安全擦除命令的review中显示,在他们研究的超过12个型号SSD中,只有8个提供了ATA安全擦除功能,而在这8个硬盘中,三个都有各种bug[11]

对于性能的影响是很重要的,并且在安全方面更加重要,但我不想展开说。这里有几个Stack Overflow上的讨论可以解释关于如何可靠地删除SSD中的数据的细节。

5.4 原生命令队列(NCQ)

原生命令队列(NCQ)是SATA的一个功能,其允许SSD接受来自主机的多个命令,使SSD可以使用内部并行同时完成这些命令[3]。除了减少因为硬盘造成的延迟外,一些新的硬盘同样使用NCQ来应对来自主机的延迟。例如NCQ可以优先传入的命令来确保当主机CPU忙的时候硬盘总是有命令处理。

5.5 断电保护

无论是在家还是在数据中心,断电都是有可能发生的。一些生产商在他们的SSD结构中设置有超级电容,这个电容设计为存有足够提交总线中所有I/O请求所需的能量以防掉电。问题在于并非所有的SSD生产商都为他们的硬盘设置超级电容或者某种掉电保护,而有超级电容的不总是在说明书中提及。然后,和安全擦除命令一样,断电保护机制的实现是否正确,并且是否确实能够在掉电时避免数据损坏是搞不清楚的。

Zheng等人2013年的研究中测试了15个SSD,但没有透露品牌[72]。他们给硬盘各种各样的电源故障,发现测试的15个SSD中有13个最终丢失数据或者大规模的数据损坏。在另外一篇Luke
Kenneth Casson Leighton写的关于电源故障的文章中显示出,测试的4个硬盘有3个最终都在不正确的状态,剩下的一个没有问题(是Intel的硬盘)[73] 。

SSD还是一个非常年轻的技术,并且我相信这些电源故障下造成数据损坏的阻力将会在接下来的产品中克服。然而现在,在数据中心配置不间断电源(UPS)可能还是应该做的。并且和任何其他存储解决方案一样,经常备份敏感数据。

6.SSD中的内部并行

6.1 总线带宽限制

因为物理限制的存在,异步NAND闪存I/O总线无法提供32-40 MB/s以上的带宽[5]。SSD生产商提升性能的唯一办法是以某种方法让他们的硬盘中的多个存储芯片可以并行或者交错。[2]的2.2节中有一个比较好的关于交错的解释。

通过组合SSD内所有层次的内部并行,不同芯片中的多个块可以作为一个叫clustered block(直译是集群块,但我感觉用比较亲切,本译文中所有的簇都是指它)东西同时访问。我不打算解释关于SSD内部并行的所有细节,因此我只简述一下并行的层次和簇。获取更多关于这个话题的信息,以及SSD内部并行的概括,这里的两篇论文是很好的开始[2,
3]
。此外,一些高级命令如copybackinter-plane transfer[5]中有阐述。

内部并行

在SSD内部,数个层次的并行允许一次将数个块写入到不同的NAND闪存芯片中,这些块称为簇。

6.2 并行的多级别

下边的图6展示了NAND闪存芯片的内部,其组织为一种分级的结构。这些级别包括通道、封装、芯片、面、块和页。如[3]中揭示的,这些不同的层通过下边的方法提供并行

  • 通道级并行 闪存主控和闪存封装之间的通信通过数个通道。这些通道可以独立或者同时访问。每个独立通道有数个封装共享。
  • 封装级并行 一个通道中的不同封装可以独立访问。交错可以使命令同时在同一个通道中的不同封装中运行。
  • 芯片级并行 一个封装包含两个或者更多的芯片,芯片可以并行独立访问。注:芯片通常也被称为核心(chips are also called “dies”)
  • 面级并行 一个芯片包含两个或者更多的面。相同的操作(读、写或者擦除)可以在芯片中多个面上同时运行。面包含了块,块包含了页。面也包含了寄存器(小RAM缓存),其用在面级操作上。

图6: NAND 闪存封装

6.3 簇

译注: 本节标题原文是“clustered blocks”,词典上没有这个词(词组?),Google了也没有发现合适的翻译,其直译是“集群的块”或者“成簇的块”。因为这个“clustered blocks”和“簇”的英文“Data cluster”比较像,特性上也相似(都是若干存储单位的集合),决定将这个“clustered blocks”在本文中译为“簇”。但这个簇与机械硬盘的簇不是相同的东西,请读者注意分辨。如果有更为合适或者正规的翻译请告诉我。

从多个芯片中访问到的多个块被称为一个簇[2]。这个做法比较像RAID系统中的striping[1,
5]

一次访问的逻辑块地址被分到不同SSD闪存封装中的不同芯片上。这归功于FTL的映射算法,并且这与这些地址是否连续无关。分割块允许同时使用多个通道来整合其带宽,并同样可以并行执行多个读、写和擦除操作。这即表示I/O操作按簇大小对齐来确保SSD中多个级别的内部并行所提供的性能能够最大程度的利用。

为SSD编程(4)——高级功能和内部并行

时间: 2024-10-24 19:14:05

为SSD编程(4)——高级功能和内部并行的相关文章

十三、Python高级功能之面向对象编程

Python高级功能之面向对象编程(类和对象) 一.类和对象: 面向过程和面向对象的编程 面向过程的编程:函数式编程,C程序等 面向对象的编程:C++,Java,Python等 类和对象:是面向对象中的两个重要概念 类:是对事物的抽象,比如:汽车模型 对象:是类的一个实例,比如:QQ轿车.大客车 范例说明: 汽车模型可以对汽车的特征和行为进行抽象,然后可以实例话为一台真实的汽车实体出来 二.Python类定义 Python类的定义: 使用class关键字定义一个类,并且类名的首字母要大写: 当程

Linux环境编程之高级I/O(一):非阻塞I/O、记录锁

引言:高级I/O包括非阻塞I/O.记录锁.系统V流机制.I/O多路转接(select和poll函数).readv和writev函数以及存储映射I/O. (一)非阻塞I/O 可能会使进程永远阻塞的一类系统调用有: 1.如果某些文件类型的数据并不存在,则读操作可能会使调用者永远阻塞. 2.如果数据不能立即被上述同样类型的文件接受,则写操作也会使调用者永远阻塞. 3.在某种条件发生之前,打开某些类型的文件会阻塞. 4.对已经加上强制记录锁的文件进行读.写. 5.某些ioctl操作. 6.某些进程间通信

vim 高级功能

本文章原创首发于公众号:编程三分钟 ,文末二维码. 文本编辑.跳转.删除.复制.替换这些操作用vim确实是快:但是好像仅仅是这样根本不能说服我vim超过鼠标的地方. 花点时间弄熟这些,除了炫技意外,主要为了防止深夜被拉起来救火,机房还不能远程,连夜打车到了地方,却发现服务器没有图形化界面,这个时候要是脚本写的熟,vim操作6几下修复完了,能尽量降低损失,也能睡个好觉了. 高级功能入门 常用操作在之间的文章我们已经已经掌握了,接下来就要搞一点高级操作,基本谁看见都要感叹一声"你vim怎么这么6!.

PHP命名空间规则解析及高级功能

日前发布的PHP 5.3中,最重要的一个新特性就是命名空间的加入.本文介绍了PHP命名空间的一些术语,其解析规则,以及一些高级功能的应用,希望能够帮助读者在项目中真正使用命名空间. 在这里中我们介绍了PHP命名空间的用途和namespace关键字,在这篇文章中我们将介绍一下use命令的使用以及PHP如何解析命名空间的名字的. 为了便于对比,我定义了两个几乎一样的代码块,只有命名空间的名字不同. < ?php // application library 1 namespace App\Lib1;

block高级功能

/* -*- c++ -*- */ /* * Copyright 2004,2007,2009,2010,2013 Free Software Foundation, Inc. * * This file is part of GNU Radio * * GNU Radio is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License a

MVC5+EF6--12 Entity Framework高级功能

近期学习MVC5+EF6,找到了Microsoft的原文,一个非常棒的系列,Getting Started with Entity Framework 6 Code First using MVC 5,网址:http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/creating-an-entity-framework-data-model-for-an-asp-net-mvc-appli

编程题:功能:将5个学生记录输入文件d:\stu1.txt中,并且显示在屏幕上。

编程题:文件读写fprintf().fscanf()使用,功能:将5个学生记录输入文件d:\stu1.txt中,并且显示在屏幕上. #include<stdio.h> void main() { FILE *fp;long num;int n,score;char name[20]; int N=5; fp=fopen("d:\\s tu1.txt","w"); for(n=1;n<=N;n++) { scanf("%s%10ld%d&q

iOS开发——UI篇Swift篇&amp;玩转UItableView(二)高级功能

UItableView高级功能 1 class UITableViewControllerAF: UIViewController, UITableViewDataSource, UITableViewDelegate { 2 3 var titleString:String! 4 5 @IBOutlet var titleLabel:UILabel! 6 @IBOutlet var listTableView : UITableView! 7 @IBOutlet var editDoneBut

[渣译文] 使用 MVC 5 的 EF6 Code First 入门 系列:为ASP.NET MVC应用程序使用高级功能

这是微软官方教程Getting Started with Entity Framework 6 Code First using MVC 5 系列的翻译,这里是第十二篇:为ASP.NET MVC应用程序使用高级功能 原文:Advanced Entity Framework 6 Scenarios for an MVC 5 Web Application 译文版权所有,谢绝全文转载--但您可以在您的网站上添加到该教程的链接. 在之前的教程中,您已经实现了继承.本教程引入了当你在使用实体框架Code