23-存储案例:如何降低SSD峰值延迟

摘要:
我们这一讲就探讨存储方面的优化案例,是关于SSD性能的。也就是说,SSD内部需要进行块级别的“垃圾回收”。因此,对SSD的写入需求,比对HDD的写入需求更高。换句话说,很高的写入速率,可能会导致SSD在到达其预期使用寿命之前就发生故障。比如一个SSD预期寿命是4年。如何减少SSD损耗?Trim的使用,虽然带来了降低SSD损耗的好处,但也带来了一些坏处,特别是IO访问可能延迟加大的问题。原因和SSD内部的实际机制有关。

我们之前讲过,存储系统的性能很关键(参见第17讲)。我们这一讲就探讨存储方面的优化案例,是关于SSD性能的。

现在很多公司里面的高性能存储系统,一般都是基于SSD的,这主要归功于SSD价格在近几年的大幅度下降。但是,SSD也不是包治百病的灵丹妙药,也有自己的特殊性能问题。我们今天就重点讲述两点:SSD的损耗IO访问延迟偶尔过大的问题。

这里的第二个问题可能听起来很让人吃惊:不是说SSD延迟很低吗?

一般情况下,是的。但是特殊情况下就不一定了,这个就说来话长了,它和SSD的内部原理有关。我们会一步步地探讨问题形成的原因和解决的策略。

SSD为什么会损耗?

我们的第17讲是关于存储系统的,讲过SSD的工作原理和性能。为了防止你忘记,我们就在这里快速地回顾一下其中的一个重要概念:写入放大

什么是写入放大呢?当写入SSD的物理数据量,大于应用程序打算写入SSD的逻辑数据量时,就会造成“写入放大”。

如果是传统硬盘HDD,就不会有写入放大的问题。那么SSD为什么会有写入放大呢?这是因为SSD内部的工作原理和硬盘很不一样。

我们知道,HDD是可以直接写入覆盖的。和HDD不同,SSD里面的页面只能写入一次,要重写的话,必须先回收擦除,而且只能在“块”这个级别进行擦除。因此呢,SSD内部就需要不断地移动所存储的数据,来清空需要回收的块。也就是说,SSD内部需要进行块级别的“垃圾回收”。垃圾收集器必须有效地在SSD内部不断地回收块,回收以前使用的页面空间,然后才能在这个块上写入新数据。

因此,对SSD的写入需求,比对HDD的写入需求更高。

写入放大的缺点是什么?就是会更快地损耗SSD的生命

每个SSD都有固定数量的擦除周期,如果在很短时间内写到SSD太多数据,就会导致SSD损耗太快,有可能过早烧坏SSD。换句话说,很高的写入速率,可能会导致SSD在到达其预期使用寿命之前就发生故障。

所以,我们要注意一个常用的指标叫:年损耗率(Burn Rate)。这个指标是怎么定义的呢?是用SSD的预期寿命推导出来的。比如一个SSD预期寿命是4年。那么每年可以损耗25%,这就是年损耗率。

如何减少SSD损耗?

前面讲的“写入放大”,其实也可以用一个相应的具体指标来衡量,就是“写入放大系数”;它代表物理写入SSD的数据与应用程序写入的逻辑数据之比。比如,如果写入放大系数是2,就表示写入每10KB的逻辑数据,SSD实际上写了20KB。为了控制SSD的年损耗率,我们需要尽量降低写入放大系数。

那么如何减少写入放大系数呢?常见的方法有两种:

  1. 保留一定的空闲存储空间,这是因为写入放大系数是和SSD存储空闲率相关的。
  2. 使用Trim

这两种方法可以同时使用,我们下面分别介绍。

我们先简单说一下第一种方法。每个SSD都有一定数量的预留空间,这个空间不是SSD可用容量的一部分。这样做是有原因的。尽管我们可以使用工具来调整SSD卡上的可用容量,但是我不建议你减少预配置的可用空间,因为这将降低写入性能,并可能大大缩减SSD的使用寿命。

我们在存储数据到SSD时候,也不要存得太满,也就是不要追求太高的空间使用率。那么我们将SSD可用存储容量的使用率目标定为多少比较合适呢?一般来说,我们可以定为80%至85%,以保持较低的写入放大率。

SSD的空闲可用空间越多,内部垃圾收集的开销就越低,就越有可能降低写入放大系数。但是这种关系不是线性的,所以存在着收益递减的问题。

第二种方法是用Trim。我首先为你讲解一下什么是Trim。

Trim是个命令,是操作系统发给SSD控制器的特殊命令。使用Trim命令,操作系统可以通知SSD某些页面存储的数据不再有效了。比如,对于文件删除操作,操作系统会将文件的扇区标记为空闲,以容纳新数据,然后就可以将Trim命令发送到SSD。

Trim命令有什么好处呢?

SSD收到Trim命令后,SSD内部的控制器会更新其内部数据页面地图,以便在写入新数据时不去保留无效页面。并且,在垃圾回收期间不会复制无效页面,这样就实现了更有效的垃圾收集,也就减少了写操作和写入放大系数,同时获得了更高的写吞吐量,延长了驱动器的使用寿命。

Trim命令和机制虽然看起来很美好,但是实际中会产生一些问题。原因在于,不同的SSD厂商对Trim命令的处理方式,以及具体的垃圾回收机制很不一样;有的实现还不错,有的就差强人意了,因此Trim的性能在每种SSD那里会有所不同。我们后面会提到,有些SSD的厂商的某些SSD,因为对Trim的支持不太好,会造成某些情况下性能非常差。

还要注意的是,默认情况下,操作系统一般不启用Trim。因此,当文件系统删除文件时,它只是将数据块标记为“未使用”。但是SSD控制器并不知道设备上的哪些页面可用,因此无法真正释放设备上的无效空间。所以,在没有启动Trim的情况下,一旦SSD设备的可用容量填满,即使文件系统知道设备上有可用容量,SSD也会认为它自己已经存满。

那么怎么启动Trim呢?要在SSD上启用连续Trim,必须在mount这块SSD的时候使用“Discard”安装选项。如果一块SSD已经安装了,想启动Trim,那就需要卸载后重新安装,“Discard”选项才能生效。也就是说,使用remount命令是不起作用的。

所以,对于单个系统而言,最好在grub中启用mount选项,并重新启动。

想减少SSD损耗,却导致访问延迟过大?

Trim的使用,虽然带来了降低SSD损耗的好处,但也带来了一些坏处,特别是IO访问可能延迟加大的问题。

为什么Trim会影响应用程序性能呢?

原因和SSD内部的实际机制有关。每个SSD内部都有一个FTL(Flash Translation Layer)映射表,该表将操作系统的逻辑块地址(LBA,Logical Block Address)映射到SSD上的物理页面地址(PPA,Physical Page Address)。映射表在驱动器被写入时不断更新,以后每个读取和写入IO都要引用。

一般来说,映射表是存储在SSD驱动器的RAM中,以便快速访问;但是它的副本也存储在SSD中,目的是在电源故障时能够保留LBA到PPA的映射。随着SSD上面内容和数据的不断变化,这些变化包括新写入IO或垃圾回收,RAM中的映射表也不断更新,并且持续写入SSD中。

如果在文件系统上启用了Discard选项,那么每次删除文件时,都会生成Trim命令。因为每次Trim都会更改映射表,所以对映射表的更改也就实际地记录到SSD中。这项操作可能需要花费比较长的时间,比如几毫秒的时间才能完成,在这个更改过程中,普通的数据读取和写入I /O会阻塞,并且阻塞到所有的映射表调整都被完全处理为止。当今业界的大多数SSD都是这样工作的。

上面我们看到,由于Trim的处理会阻塞普通的数据读取和写入I /O,直到Trim完成映射表记录才返回,所以Trim的延迟对普通读写I O的延迟具有重大影响,尤其对高分位数(比如P99、P99.9)的读写IO延迟影响更大。减少Trim延迟就是减少IO延迟。所以,我们需要尽量减少Trim的等待处理时间。

另外值得你注意的是,每个SSD厂商和每款SSD,对Trim的具体处理方式都可能不同,颇有些厂商的某些SSD具有严重的问题。我们生产实践中碰到过好几种这样的SSD,比如有厂商的一种SSD在大量删除数据时有很大的延迟。这就要求我们在选购SSD时候,要特别小心,尤其是要做彻底的性能测试。

如何避免Trim带来的延迟?

我们刚才讲了用Trim的好处和坏处。好处是可以减少SSD的损耗,延长SSD的寿命;坏处是会造成应用程序的IO读写延迟变大。

那么怎么才能尽量避免Trim带来的坏处呢?我们这里谈两种方式:一是对Discard选项本身的调优,二是使用fstrim命令。这两种方式分别对应使用Discard被启用和不被启用的两种情况。

第一种方式是在启用了Discard后,对Discard的调优。对于已经启用Discard的场景下,Trim命令默认是没有大小限制,也就是说,一次发送会尽可能多的删除命令。但是如果一次删除的数据太多,SSD可能需要很长的时间才能返回,其他读写IO就会感受到很大的延迟。

那么我们就可以微调了,这里我们就可以借助另外一个参数,discard_max_bytes对Discard进行调优。这个参数是一个操作系统内核参数,从名字也听得出,它可以指定一次Trim的最大数据量。

调整这个参数的优点,是可以根据实际可接受IO延迟的需要,来随意微调。举个例子,假如可接受IO延迟比较大,那就可以设置一个较大的discard_max_byes数值,比如2GB。使用这个参数的坏处是,当有大文件删除时,如果没有相应的重新调整参数,Trim的吞吐量会受影响。

第二种方式,是在没有启用Discard的场景下,采用fstrim来调优。fstrim也是一个命令,它可以控制Trim,来删除掉SSD上的文件系统不再使用的数据。默认情况下,fstrim将删除文件系统中所有未使用的块,但是这个命令有其他的选项,根据删除范围或大小来进行微调。

这个命令一般用于Discard没有被启用的场景下。为了达到最好的效果,都是周期性的,或者采用外部事件触发来运行这个命令,比如用Cron来每天固定时间运行;或者每当SSD存储使用率到了某个大小就运行。

下图展示了一个实际生产环境中的性能数据。

23-存储案例:如何降低SSD峰值延迟第1张

这是一个采用fstrim而降低IO延迟的例子。横轴是时间,纵轴是对SSD进行读操作的IO延迟。红色箭头是运行fstrim的时间。我们可以看到,在fstrim后,IO延迟大幅度地降低了。

采用fstrim这个方式的优点是,可以根据实际需要来决定何时运行,并且更好地微调和控制Trim的工作。

这个方式也有缺点,就是如果不够小心,运行这个命令时可能导致很长时间的SSD读写挂起阻塞,在这个阻塞的过程中,SSD完全没有响应,不能读写。我见过几次这样的生产例子,阻塞了好几分钟甚至几个小时的时间,整个SSD完全不能写入和读取数据。

总结

SSD不断地重写会损坏其存储能力,就如同一口宝刀,不断地征战砍伐后,也会有缺口。这让我想起了唐代诗人马戴写的一首气势磅礴的《出塞词》:“金带连环束战袍,马头冲雪度临洮。卷旗夜劫单于帐,乱斫胡兵缺宝刀。”

23-存储案例:如何降低SSD峰值延迟第2张

为了延长SSD的寿命,我们可以采用Trim方式,以去除不必要的内部重写。

但是这种方式在某些特殊情况下,会增大外部IO的访问延迟。解决这一问题的方法是对Trim进行调优。我们这一讲就集中探讨了几种调优解决方案,来解决这一特殊情况下的问题。

免责声明:文章转载自《23-存储案例:如何降低SSD峰值延迟》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇java中读取资源文件的方法SQL Server 列存储索引 第一篇:概述下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

在win7系统下安装把Ubuntu17.04安装在另一个硬盘开机无法进入Ubuntu问题的一种解决办法。【转】

本文转载自:http://blog.csdn.net/u012879090/article/details/74937762 在win7系统下安装把Ubuntu17.04安装在另一个硬盘开机无法进入Ubuntu问题的一种解决办法。 本人笔记本本来装的Ubuntu(在固态硬盘中)和win7(在机械硬盘中)双系统好好的。但是为了看嵌入式视频,同时安装虚拟机并在...

T420s成功加装固态硬盘(SSD)

目的 为了提升系统和经常使用工具的启动速度,ThinkPad T420s光驱位加一块固态硬盘。 操作步骤 购买:没做太多对照了解,初步计划是安装在光驱位,直接JD上买了SanDisk的128G和推荐的硬盘架。 拆卸光驱:光驱位背面有个锁标志的卡扣。推到开锁位置同一时候往光驱开口方向推旁边的开关,光驱非常easy就推出了。 安装SSD到硬盘架:将随硬盘...

WinPE无法识别NVMe SSD硬盘,如何重装系统

(源自网络出处不详) 抽风,diy一台新机器,下载的win10系统安装时出现如题所示的问题,开始以为是主板的问题设置u盘启动也不行,后来在某个群里有人说是系统版本问题,无奈重新做了启动优盘(用的17年的win10系统当时这系统有毛病,但是为了测试机器没问题就硬着头皮装了,最终确认机器没问题, 就重新下载了一个系统镜像,只能说显卡驱动很关键!显卡驱动很关键!...

SSD固态盘应用于Ceph集群的四种典型使用场景

在虚拟化及云计算技术大规模应用于企业数据中心的科技潮流中,存储性能无疑是企业核心应用是否虚拟化、云化的关键指标之一。传统的做法是升级存储设备,但这没解决根本问题,性能和容量不能兼顾,并且解决不好设备利旧问题。因此,企业迫切需要一种大规模分布式存储管理软件,能充分利用已有硬件资源,在可控成本范围内提供最佳的存储性能,并能根据业务需求变化,从容量和性能两方面同...

联想笔记本如何安装固态硬盘-联想G50-80如何安装固态硬盘(全流程+装系统)

在现在,大家普遍想让自己的电脑运行的更流畅,于是装固态就成了一个不错的选择。下面以联想G50-80为例介绍如何加装固态。 一、硬件准备 联想G50-80 东芝固态硬盘:TOSHIBA TR2000 480G(参考价格:379元人民币) 启动U盘(用于装系统,需要事先制作好) 二、详细步骤 1、断电、关机。拔掉电源插头,关机。一定确保电脑断电、关机,严禁...

macbookpro2013升级1T的ssd

rmbp256g,乞丐版 256g的容量,安装软件得处处小心。。。 前期功课 在b站上看了一些拆解升级ssd的视频,做了一些功课,了解了我这个型号的,Retina, 13-inch, Late 2013,ssd不是在硬盘上焊死的,可以升级。了解了拆机过程和对应需要的工具后,就是上万能的tb了 前期软件准备 mac系统安装u盘(耗时大概半小时) sudo /...