性能:如何彻底发挥SSD的潜力

为什么要设计SSD友好的软件

使用SSD作为存储时,应用程序可以获得更好的IO性能。但是这些收益,主要归因于SSD提供更高的IOPS和带宽。但SSD不仅仅是“更快的HDD”。如果在设计软件时,能够充分考虑SSD的工作特点,把应用程序和文件系统设计为“对SSD友好”,会使得服务性能有个质的飞跃。

设计对SSD友好的软件的好处:

  • 提升应用程序等软件的性能
  • 提高SSD的IO效率
  • 延长SSD的寿命

更好的应用程序性能

  • 通过使用多个并发线程来执行IO
  • 多个IO线程对HDD是毫无益处的,因为HDD只有一个磁头

更高效的存储IO

  • SSD上最小内部IO单元是一页,比如4KB大小。因此对SSD的单字节读/写,必须在页面级进行。应用程序对SSD的写操作,可能会导致对SSD上的物理写操作变大,这就是“写入放大”
  • 因为有这个特性,如果应用程序的数据结构或IO对SSD不友好,就会让写入放大效果更大,导致SSD的IO不能被充分利用。

延迟SSD的寿命

SSD会磨损,是因为每个存储单元,只能维持有限数量的写入擦除周期。实际上,SSD的寿命取决于四个因素:

  • SSD大小
  • 最大擦除周期数
  • 写入放大系数
  • 应用程序写入速率

怎么设计对 SSD 友好的软件?

文件系统

第一个可以对 SSD 友好的领域是文件系统。文件系统层直接处理存储,因此我们需要在此级别进行优化设计更改,来更有效的发挥SSD的特长。一般而言,这些设计更改集中在SSD和HDD三个关键特性上:

  • SSD的随机访问和顺序访问具有相同的功能
  • 需要在块级别进行擦除后才能重写
  • 内部损耗均衡的机制会导致写入放大

现在比较流行的有两种对 SSD 友好的文件系统。第一种,是适用于 SSD 的通用文件系统,主要支持 Trim 的新功能,比如 Ext4 和 Btrfs。第二种,是专门为 SSD 设计的文件系统。基本思想是采用日志结构的数据布局(相对于 B 树或 Htree),来容纳 SSD 的“复制- 修改 - 写入”属性,比如 NVFS(非易失性文件系统)、FFS / JFFS2 和 F2FS。

数据库系统

除了文件系统,数据库系统也可以设计成对 SSD 友好。

  • SSD和HDD之间的差异在数据库设计中尤其重要。近几十年来,数据库的各个组件都已经在考虑HDD特性的情况下进行了很多优化。比如,因为普通硬盘的随机访问比顺序访问慢很多,所以数据库组件会尽量减少随机访问。而使用SSD时,类似这样的假设就不成立了
  • 因此,业界设计了新的、对 SSD 友好的数据库。对 SSD 友好的数据库主要有两种:第一种是专门针对 SSD 的数据库,例如 AreoSpike,这种数据库主要采用对 SSD 友好的 Join算法;第二种是 HDD 和 SSD 混合的数据库,一般是使用 SSD 来缓存数据。

数据基础架构层

第三个领域是数据基础架构层。

  • 对于分布式数据系统设计而言,数据来源大体上有两个地方:计算机的本地磁盘或者另一台计算机上的内存。这两个来源哪个更快更高效呢?不一定
  • 过去,倾向于远程计算机的内存。传统的本地HDD访问延迟,大约是好几个毫秒,而远程内存访问的延迟,包括了RAM访问延迟和网络传输延迟,也仅处于微秒级。同时,远程内存的IO带宽与本地HDD大致相同甚至更多。因此,远端内存反而比本地硬盘的访问时间更短
  • 而SSD的出现,改变了这个争论。使用SSD作为存储设备后,本地SSD变得比远程内存访问更为高效。SSD的IO延迟降低到了微秒级别,而IO带宽比HDD高一个数量级。这些结构就导致了数据基础架构层的新设计。比如,新设计更希望尽可能的与应用程序共同分配数据,以避免额外的节点和网络的限制,从而降低系统的复杂性和成本

应用层

在这里插入图片描述

数据结构:避免就地更新优化

  • 传统的HDD的寻址延迟很大,因此,使用HDD的应用程序通常会进行各种优化,以执行不需要寻址的就地更新,比如只在一个文件后面写入

  • 比如下图所示,在执行随机更新时,吞吐量一般只能达到约 170 QPS;而对于同一个HDD,就地更新可以达到 280QPS,远高于随机更新
    在这里插入图片描述

  • 不过在设计与 SSD 配合使用的应用程序时,这些考虑就没什么意义了。对 SSD 而言,随机读写和顺序读写性能类似,就地更新不会获得任何 IOPS 优势

  • 此外,就地更新实际上是会导致SSD性能下降的。包含数据的SSD页面无法直接重写,因此在更新存储的数据时,必须先将相应的SSD页面读入SSD缓冲区,然后将数据写入感觉的页面。SSD 中的“读取 - 修改 - 写入”过程与 HDD 上的直接“仅写入”行为形成了鲜明的对比

  • 而SSD上的随机更新,就不会引入读取和修改步骤(即仅仅“写入”),因此速度更快

  • 使用 SSD,以上相同的应用程序,可以通过随机更新或就地更新来达到大约 2 万 QPS;而且随机更新和就地更新的吞吐量大体相似,随机更新其实还稍微好些。如下图所示。
    在这里插入图片描述

数据结构:区分热、冷数据

  • 几乎所有处理存储的应用程序,磁盘上存储的数据访问概率均不相同。

  • 在更新数据时,SSD需要在页面级别进行访问。因此,如果数据大小小于一页,那么每次读取数据时,附加的数据也会被一起访问。如果应用程序其实并不需要附近的数据,那么额外的数据访问,不仅会浪费IO带宽,而且会不必要的磨损SSD。

  • 为了缓解这种性能问题,在将SSD作为存储设备时,应该将热数据和冷数据分开。以不同级别或者不同方式来分隔。

数据结构:采用紧凑的数据结构

  • 在SSD的世界中,最小的更新单位是页面(4KB),因此,即使是一个字节的更新,也将导致至少4KB SSD的写入。由于写入放大的效果,实际写入的SSD的字节可能远大于4KB。读取操作也是类似,因为OS具有预读机制,会预先主动地读入文件数据,以期改善读取文件时的缓存命中率

  • 所以,当将数据保留在SSD上时,最好使用紧凑的数据结构,避免分散的更新,以获得更快的应用程序性能、更有效的存储IO以及节省SSD的寿命

IO处理:避免长而繁重的持续写入

SSD通常具有GC机制,不断地回收存储块以供以后使用。GC可以用前台或者后台的方式工作。

  • SSD控制器通常保持一个空闲块的阈值。每当可用块数下降到阈值以下时,后台GC就会启动。由于后台GC是异步发生的(即非阻塞),因此它不会影响应用程序的IO延迟。 但是,如果块的请求速率超过了GC速率,并且后台GC无法跟上,则将触发前台GC
  • 在前台GC期间,必须即使擦除(即阻塞)每个块以供应用程序使用,这时发出写操作的应用程序所经历的写延迟就会受到影响。具体来说,释放块的前台GC操作,可能会花费数毫秒以上的时间,从而导致较大的应用程序IO延迟。

因此,最好避免进行长时间的大量写入操作,这样就可能永远不触发前台GC

IO处理:避免SSD存储太满

SSD磁盘存储的满村程度,会影响写入放大系数和GC到导致的写入性能。

  • 在GC期间,需要擦除块以创建空闲块。
  • 擦除块之前,需要移动并保留有效数据才能获得空闲块
  • 有时为了获得一个空闲块,需要压缩好几个存储块
  • 而每个空闲块的生存需要压缩的块数,取决于磁盘的空间使用率

假设磁盘满百分比平均为 A%,要释放一个块,则需要压缩 1 /(1-A%)块。显然,SSD的空间使用率越高,将需要移动更多的块以释放一个块,这将占用更多的资源,并导致更长的 I/O 等待时间。

例如,如果 A=80%,则大约移动五个数据块以释放一个块。当 A=95%时,将移动约 20个块。

线程:使用多个线程执行小的IO

SSD内部大量使用了并行的设计,这种并行表现在多个层面上。一个IO线程无法充分利用这些并行性,会导致访问时间更长。而使用多个线程,就可以充分利用SSD内部的并行性了

  • SSD可以有效地在可用通道间分配读写操作,从而提高高水平的内部IO并发性
  • 例如,我们使用一个应用程序执行 10KB 写入 I/O(10KB 算是比较小的 IO 大小)。使用一个 I/O 线程,它可以达到 115MB/ 秒。使用两个线程基本上使吞吐量加倍;使用四个线程再次将其加倍;使用八个线程可达到约 500MB/ 秒,如下图所示。
    在这里插入图片描述

问题:这里的“小”,到达有多小

答案是:只要是不能充分利用内部并行性的任何IO大小,都被视为“小”。例如,SSD页面大小为 4KB,内部并行度为 16,则阈值应约为 64KB。

线程:使用较小的线程来执行大IO

对于大型IO,SSD内部已经充分优化了SSD的内部并行性,因此,应该使用更少的线程(小于4个)以实现更大的IO吞吐量。

  • 从吞吐量的角度来看,用太多线程不会有太大益处。
  • 更重要的是,使用太多线程可能导致线程之间的资源竞争,以及诸如 OS 级的预读和回写之类的后台活动。
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值