优化永久性磁盘和本地 SSD 性能

永久性磁盘因其价格实惠、性能优异并且耐用性强而成为最常用的存储方案。您还可以选择使用本地 SSD,它们可以提供更高的性能和更低的延迟时间,但不具备冗余性,并且仅在特定实例的生命周期内存在。为在实例上运行的应用配置存储方案时,请遵循以下过程:

  • 确定您需要的空间数量。
  • 确定您的应用所需的性能特征。
  • 配置实例以优化存储性能。

以下部分介绍了可以挂接到 Compute Engine 实例的可用块存储方案。如需查看 Google Cloud Platform 上存储方案的完整列表,请参阅 Cloud Storage 产品

块存储性能比较

请考虑您的存储空间大小和性能要求,这样有助于您确定适用于您的实例的正确磁盘类型和大小。一个给定应用的性能要求通常分为两种不同的 I/O 模式。

  • 小批量读写操作
  • 大批量读写操作

对于小批量读写操作,其限制因素是随机每秒输入/输出操作次数 IOPS

对于大批量读写操作,其限制因素是吞吐量

IOPS/GB 和吞吐量数字表示单个磁盘上数据的总聚合性能,无论该磁盘是挂接到单个实例还是跨多个实例共享,都是如此。对于多个实例从同一磁盘读取数据的情况,磁盘的聚合吞吐量和 IOPS 容量会在这些实例之间共享。为了规划目的,我们建议您使用以下 IOPS/GB 和吞吐量速率。

地区
标准
永久性磁盘
区域
标准
永久性磁盘
地区
SSD
永久性磁盘
区域
SSD
永久性磁盘
本地 SSD (SCSI) 本地 SSD (NVMe)
最大持续 IOPS
读取 IOPS/GB 0.75 0.75 30 30 266.7 453.3
写入 IOPS/GB 1.5 1.5 30 30 186.7 240
读取 IOPS/实例 3000* 3000* 15000–60000* 15000–60000* 400000 680000
写入 IOPS/实例 15000* 15000* 15000–30000* 15000–30000* 280000 360000
最大持续吞吐量 (MB/s)
读取吞吐量/GB 0.12 0.12 0.48 0.48 1.04 1.77
写入吞吐量/GB 0.12 0.12 0.48 0.48 0.73 0.94
读取吞吐量/实例 240* 240* 240–1200* 240–1200* 1560 2650
写入吞吐量/实例 76 - 240** 38 - 200** 76–400* 38–200* 1090 1400

* 永久性磁盘 IOPS 和吞吐量性能取决于实例 vCPU 的数量和 IO 块大小。请参阅 SSD 永久性磁盘性能限制了解有关 SSD 永久性磁盘的详情,并请参阅标准永久性磁盘性能限制了解有关标准永久性磁盘的详情。

** SSD 和标准永久性磁盘可以在具有更多 vCPU 的实例上实现更高的吞吐量性能。如需了解详情,请参阅针对写入吞吐量的网络出站流量上限

将永久性磁盘与物理硬盘进行比较

在您指定永久性磁盘的容量大小时,请考虑这些磁盘与传统物理硬盘之间的对比情况。下表将标准永久性磁盘和 SSD 永久性磁盘与 7200 RPM SATA 硬盘的典型性能进行了比较,后者通常可达到 75 IOPS 或 120 MB/秒。

I/O 类型 I/O 模式 要达到与 7200 RPM SATA 硬盘同等的性能所需的容量大小
标准永久性磁盘 SSD 永久性磁盘
小批量随机读取次数 75 次小批量随机读取 100 GB 3 GB
小批量随机写入 75 次小批量随机写入 50 GB 3 GB
流式大批量读取 120 MB/秒的流式读取 1000 GB 250 GB
流式大批量写入 120 MB/秒的流式写入 1000 GB 250 GB

容量大小、价格和性能摘要

虽然您在为应用选择卷类型和大小时需要考虑若干因素,但您不需要考虑的一个因素就是卷的使用费用。永久性磁盘不是根据 I/O 数据量来计费的,因此您无需通过估算每月 I/O 数据量来计算将要用在磁盘上的预算。但是,对于面向 IOPS 的工作负载,为了便于比较,您可以分解每月费用以了解每次 IOPS 的价格。

以下价格计算示例使用的是美国永久性磁盘价格。在这些示例中,请考虑标准永久性磁盘与 SSD 永久性磁盘相比较的相对成本。标准永久性磁盘的价格为每 GB $0.040,而 SSD 永久性磁盘的价格为每 GB $0.170。增加卷的大小时会自动提高性能上限,无需额外费用。

如需确定永久性磁盘每次 IOPS 的费用,请将每月每 GB 的价格除以每 GB 的 IOPS 数。下表计算每 GB 每次随机读取 IOPS 的价格。您也可以使用相同的计算方法来计算每次写入 IOPS 的价格。

磁盘类型 价格(每月每 GB) 每 GB 读取 IOPS 次数 价格(每 GB 每次 IOPS)
标准永久性磁盘 $0.040 0.75 $0.040 / 0.75 = $0.0533
SSD 永久性磁盘 $0.170 30 $0.170 / 30 = $0.2267

SSD 永久性磁盘在 2000 GB 时达到 60000 次随机读取 IOPS 的上限,在 1000 GB 时达到 30000 次随机写入 IOPS 的上限。相比之下,标准永久性磁盘在 4 TB 时达到 3000 次随机读取 IOPS 的上限,在 10 TB 时达到 15000 次随机写入 IOPS 的上限。

SSD 永久性磁盘的设计旨在确保将延迟时间控制在数毫秒以内。实际的延迟时间取决于具体的应用。

标准永久性磁盘

标准永久性磁盘的性能可线性扩展至虚拟机性能上限。如果您的实例的 vCPU 数量为 4 个或更多,这并不会限制标准永久性磁盘的性能。

实例的 vCPU 数量小于 4 会降低 IOPS 的写入上限,因为网络出站流量限制与 vCPU 数量成正比。写入上限还取决于 I/O 的大小(在同一 IOPS 级别,16 KB I/O 消耗的带宽比 8 KB I/O 多)。

标准永久性磁盘的 IOPS 和吞吐量性能会随着磁盘大小线性增加,直到达到以下上限(按每个实例计算):

  • 读取吞吐量:磁盘大小为 2 TB 时最高可达到 240 MB/秒。
  • 写入吞吐量:磁盘大小为 2 TB 时最高可达到 240 MB/秒。
  • 读取 IOPS:磁盘大小为 4 TB 时最高可达到 3000 次 IOPS。
  • 写入 IOPS:磁盘大小为 10 TB 时最高可达到 15000 次 IOPS。

如需在现有的实例中获得永久性磁盘的性能优势,请调整永久性磁盘的大小以增加每块永久性磁盘的 IOPS 和吞吐量。

卷大小 (GB) 持续随机 IOPS 持续吞吐量(MB/秒)
读取
(<=16 KB/IO)
写入
(<=8 KB/IO)
写入
(16 KB/IO)
读取 写入
10 * * * * *
32 24 48 48 3 3
64 48 96 96 7 7
128 96 192 192 15 15
256 192 384 384 30 30
512 384 768 768 61 61
1000 750 1500 1500 120 120
1500 1125 2250 2250 180 180
2048 1536 3072 3072 240 240
4000 3000 6000 6000 240 240
5000 3000 7500 7500 240 240
8192 3000 12288 7500 240 240
10000 3000 15000 7500 240 240
16384 3000 15000 7500 240 240
32768 3000 15000 7500 240 240
65536 3000 15000 7500 240 240

* 只能针对启动卷使用此卷大小。I/O 爆发为启动卷提供了比此处介绍的线性扩展更高的性能。

SSD 永久性磁盘

除了磁盘大小以外,SSD 永久性磁盘的 IOPS 性能还取决于实例中的 vCPU 数量。

由于网络出站流量对写入吞吐量的限制,核心数量较少的虚拟机具有较低的写入 IOPS 和吞吐量上限。如需了解详情,请参阅写入吞吐量的网络出站流量上限

SSD 永久性磁盘的性能可线性扩展,直到达到卷的性能上限或相应 Compute Engine 实例的性能上限。SSD 读取带宽和接近上限的 IOPS 一致性在很大程度上取决于网络入站流量利用率;某种程度上的变化是正常的,特别是对于接近 IOPS 上限的 16 KB I/O。

实例的 vCPU 数量 持续随机 IOPS 持续吞吐量(MB/秒)
读取
(<=16 KB/IO)
写入
(<=8 KB/IO)
写入
(16 KB/IO)
读取* 写入
1 个 vCPU15000 9000 4500 240 72
2 到 3 个 vCPU15000 15000 4500/vCPU 240 72/vCPU
4 到 7 个 vCPU 15000 15000 15000 240 240
8 到 15 个 vCPU 15000 15000 15000 800 400
16 到 31 个 vCPU 25000 25000 25000 1200 400
32 到 63 个 vCPU 60000 30000 25000 1200 400
64 个及更多 vCPU** 60000 30000 25000 1200 400

* 基于 I/O 块大小为 256 KB 或更大值的吞吐量最大值。

** 在 CPU 完全被占用的情况下,可能无法实现最高性能。

如需提高现有实例上的 SSD 永久性磁盘的性能,请更改实例的机器类型以增加每个虚拟机的性能上限,并调整永久性磁盘的大小以增加每个永久性磁盘的 IOPS 和吞吐量。

卷大小 (GB) 持续随机 IOPS 持续吞吐量(MB/秒)
读取
(<=16 KB/IO)
写入
(<=8 KB/IO)
写入
(16 KB/IO)
读取 写入
10 300 300 300 4.8 4.8
32 960 960 960 15 15
64 1920 1920 1920 30 30
128 3840 3840 3840 61 61
256 7680 7680 7680 122 122
500 15000 15000 15000 240 240
834 25000 25000 25000 400 400
1000 30000 30000 25000 480 400
1334 40000 30000 25000 640 400
1667 50000 30000 25000 800 400
2048 60000 30000 25000 983 400
4096 60000 30000 25000 1200 400
8192 60000 30000 25000 1200 400
16384 60000 30000 25000 1200 400
32768 60000 30000 25000 1200 400
65536 60000 30000 25000 1200 400

C2 磁盘限制

计算优化的机器类型受限于每个 vCPU 的特定永久性磁盘限制,这些限制与其他机器类型的限制不同。下表展示了这些限制。

请注意,按卷来看的性能与标准磁盘性能SSD 磁盘性能部分中描述的性能相同。

标准永久性磁盘
实例的 vCPU 数量 持续随机 IOPS 持续吞吐量(MB/秒)
读取
(<=16 KB/IO)
写入
(<=8 KB/IO)
写入
(16 KB/IO)
读取* 写入
4 个 vCPU 3000 4000 4000 240 240
8 个 vCPU 3000 4000 4000 240 240
16 个 vCPU3000 4000 4000 240 240
30 个 vCPU 3000 8000 8000 240 240
60 个 vCPU 3000 15000 15000 240 240
SSD 永久性磁盘
实例的 vCPU 数量 持续随机 IOPS 持续吞吐量(MB/秒)
读取
(<=16 KB/IO)
写入
(<=8 KB/IO)
写入
(16 KB/IO)
读取* 写入
4 个 vCPU 4000 4000 4000 240 240
8 个 vCPU 4000 4000 4000 240 240
16 个 vCPU8000 4000 4000 320 240
30 个 vCPU 15000 8000 8000 600 240
60 个 vCPU 30000 15000 15000 1200 400

同时读取和写入

对于标准永久性磁盘,同时发生的读取和写入操作共享相同的资源。当您的实例使用了更高的读取吞吐量或 IOPS 时,它能够执行的写入次数就会减少。相反,如果实例使用了更高的写入吞吐量,那么它能够执行的读取次数也会减少。

SSD 永久性磁盘可以同时达到读取和写入操作的吞吐量上限。但对于 IOPS 而言并非如此;也就是说,SSD 永久性磁盘不可能同时达到其最大读取和写入上限。为了在同时执行读取和写入操作时实现最大吞吐量上限,请优化 I/O 大小,使卷能够达到其吞吐量上限,而又不至于遇到 IOPS 瓶颈。

同时读取和写入的实例 IOPS 上限:

下表中的 IOPS 数字基于 8 KB 的 I/O 大小。其他 I/O 大小(如 16 KB)可能具有不同的 IOPS 数字,但具有相同的读取/写入分配。

标准永久性磁盘 SSD 永久性磁盘(8 个 vCPU) SSD 永久性磁盘(32 个或更多 vCPU)
读取 写入 读取 写入 读取 写入
3000 IOPS 0 IOPS 15000 IOPS 0 IOPS 60000 IOPS 0 IOPS
2250 IOPS 3750 IOPS 11250 IOPS 3750 IOPS 45000 IOPS 7500 IOPS
1500 IOPS 7500 IOPS 7500 IOPS 7500 IOPS 30000 IOPS 15000 IOPS
750 IOPS 11250 IOPS 3750 IOPS 11250 IOPS 15000 IOPS 22500 IOPS
0 IOPS 15000 IOPS 0 IOPS 15000 IOPS 0 IOPS 30000 IOPS

同时读取和写入的实例吞吐量上限:

标准永久性磁盘 SSD 永久性磁盘(8 个 vCPU) SSD 永久性磁盘(16 个或更多 vCPU)
读取 写入 读取 写入 读取 写入
240 MB/秒 0 MB/秒 800 MB/秒* 400 MB/秒* 1200 MB/秒* 400 MB/秒*
180 MB/秒 60 MB/秒
120 MB/秒 120 MB/秒
60 MB/秒 180 MB/秒
0 MB/秒 240 MB/秒

* 对于 SSD 永久性磁盘,读取吞吐量最大值和写入吞吐量最大值彼此独立,因此这些上限是不变的。由于持续改进,您可能会看到超出发布上限的更高的单实例 SSD 永久性磁盘写入吞吐量。

写入吞吐量的网络出站流量上限

每个永久性磁盘写入操作都会占用虚拟机 (VM) 实例的累计网络出站流量上限

如需计算某个虚拟机实例可以发送的永久性磁盘最大写入流量,请从该实例的每个 vCPU 每秒 2 Gbit 的网络流量上限中减去其他网络出站流量。剩余的吞吐量就表示您可以用于永久性磁盘写入流量的吞吐量。

Compute Engine 永久性磁盘提供内置冗余。实例通过将数据并行写入永久性磁盘三次来实现此冗余性。此外,每个写入请求都有一定的开销,因为占用了出站流量带宽。

每个实例都具有基于虚拟机的网络出站流量上限的永久性磁盘写入限制。在永久性磁盘与 IP 流量竞争网络出站流量的情况下,网络出站流量上限的 60% 将分配给永久性磁盘流量,剩余 40% 将分配给 IP 流量。下表显示了具有和没有其他 IP 流量的永久性磁盘预期写入带宽:

标准永久性磁盘 固态永久性磁盘
vCPU 数量 标准永久性磁盘的写入上限(MB/秒) 标准永久性磁盘的写入分配(MB/秒) 达到上限所需的标准卷大小 (GB) SSD 永久性磁盘的写入上限(MB/秒) SSD 永久性磁盘的写入分配(MB/秒) 达到上限所需的 SSD 永久性磁盘大小 (GB)
1 72 43 600 72 43 150
2 144 86 1200 144 86 300
4 240 173 2000 240 173 500
8 个或更多 240 240 2000 400 346 834

如需了解此表格中的值是如何计算得出的,请参考示例(其中包含 1 个 vCPU 和标准永久性磁盘)。在此示例中,我们估计每个写入请求的带宽系数是 3.3,这意味着数据被向外写出了 3 次,并且总开销为 10%。如需计算出站流量上限,请将网络出站流量上限 2 Gbit/秒(相当于 238 MB/秒)除以 3.3:

1 个 vCPU 的最大写入带宽 = 238 / 3.3 = ~72 MB/秒(写入到您的标准永久性磁盘)

使用前面介绍的性能图表中提供的标准永久性磁盘的每 GB 写入吞吐量数据,您也可以计算得到实现上述性能所需的磁盘容量:

1 个 vCPU 要达到最大写入带宽所需的磁盘容量 = 72 / 0.12 = ~600 GB

与地区永久性磁盘类似,来自区域永久性磁盘的写入流量也会占用虚拟机实例的累计网络出站流量上限。如需计算适用于区域永久性磁盘的网络出站流量上限,请使用系数 6.6。

1 个 vCPU 的最大写入带宽 = 238 / 6.6 = ~36 MB/秒(写入到复制的标准永久性磁盘)。

优化永久性磁盘和本地 SSD 性能

您可以对永久性磁盘和本地 SSD 进行优化,以便更高效地处理您的数据。

优化永久性磁盘

永久性磁盘可以为您提供磁盘类型图表中描述的性能,前提是虚拟机必须具有足够的使用率以达到这些性能上限。在您根据性能需求调整永久性磁盘卷大小后,您的应用和操作系统可能需要进行一些细微调整。

在以下部分中,我们将介绍几个可以进行调整以获得更好性能的关键因素,以及如何将其中一些因素应用于特定类型的工作负载。

停用延迟初始化并启用 DISCARD 命令

永久性磁盘支持 DISCARD 或 TRIM 命令,借助这些命令,操作系统就能在磁盘块不再被使用时通知磁盘。对 DISCARD 命令的支持可以让操作系统将磁盘块标记为不再需要,而不会产生将块清零的费用。

在大多数 Linux 操作系统上,您可以在将某个永久性磁盘装载到实例时启用 DISCARD。当您装载永久性磁盘时,Windows 2012 R2 实例会默认启用 DISCARD。Windows 2008 R2 不支持 DISCARD。

启用 DISCARD 不仅可以改善一般运行时性能,而且还可以提高磁盘在首次装载时的性能。对整个磁盘卷进行格式化可能会非常耗时,因此“延迟格式化”是一种常见做法。延迟格式化的缺点是,这一开销通常需要在第一次装载卷时承担。通过停用延迟初始化并启用 DISCARD 命令,您可以快速地执行格式化和装载。

  • 通过将以下参数传递给 mkfs.ext4,即可停用延迟初始化并在格式化过程中启用 DISCARD:

    -E lazy_itable_init=0,lazy_journal_init=0,discard
    

    lazy_journal_init=0 参数不适用于具有 CentOS 6RHEL 6 映像的实例。对于这些实例,在格式化永久性磁盘时不要使用该参数:

    -E lazy_itable_init=0,discard
    
  • 通过将以下标志传递给 mount 命令,在装载时启用 DISCARD 命令:

    -o discard
    

启用了 discard 选项的永久性磁盘运行良好。但是,您也可以不使用 discard 选项,而选择定期运行 fstrim,或者同时运用这两种方式。如果您不使用 discard 选项,请在创建磁盘快照之前运行 fstrim。裁剪文件系统可让您创建的快照映像更小,从而减少存储快照的费用。

I/O 队列深度

许多应用都具有可以影响其 I/O 队列深度的设置。较大的队列深度可增加 IOPS,但也会增加延迟时间。较小的队列深度会降低每次 I/O 的延迟时间,但可能导致最大 IOPS 下降。

预读缓存

为了提高 I/O 性能,操作系统使用了如 readahead(预读)等技术,该技术假定后续读取可能需要文件中的某些数据,因此会将该文件中的更多内容读入内存,而不只是所请求的部分。较高的 readahead 值可增加吞吐量,但是会占用更多内存和 IOPS。较低的 readahead 值可增加 IOPS,但是会牺牲吞吐量。

在 Linux 系统上,您可以使用 blockdev 命令获取和设置 readahead 值:

$ sudo blockdev --getra /dev/[DEVICE_ID]
$ sudo blockdev --setra [VALUE] /dev/[DEVICE_ID]

readahead 值为 <desired_readahead_bytes> / 512 字节。

例如,对于一个 8 MB 的预读,8 MB 是 8388608 字节 (8 * 1024 * 1024),

8388608 bytes / 512 bytes = 16384

您需要将 blockdev 设置为 16384

$ sudo blockdev --setra 16384 /dev/[DEVICE_ID]

让 CPU 有空闲时间

读取和写入永久性磁盘都需要使用虚拟机提供的 CPU 周期。为了实现非常高而且一致的 IOPS 水平,需要让 CPU 能够有空闲时间来处理 I/O 操作。

面向 IOPS 的工作负载

无论是 SQL 数据库还是 NoSQL 数据库都具有随机访问数据的使用模式。Google 建议您为面向 IOPS 的工作负载使用以下值:

  • 每 400-800 次 IOPS 的 I/O 队列深度值为 1,对于容量较大的卷而言上限为 64

  • 针对每 2000 次随机读取 IOPS 使用 1 个空闲 CPU,针对每 2500 次随机写入 IOPS 使用 1 个空闲 CPU

MongoDBApache Cassandra 和其他数据库应用的最佳做法文档中通常建议使用较低的 readahead 值。

面向吞吐量的工作负载

流式传输操作(例如 Hadoop 作业)可受益于快速顺序读取,而较大的 I/O 大小可以提高流式传输的性能。对于面向吞吐量的工作负载,我们建议使用 256 KB 或更大的 I/O 大小。

优化 SSD 永久性磁盘的性能

各种磁盘类型的性能图表中描述了固态永久性磁盘的预期可实现的性能上限。如需优化应用和虚拟机实例以达到这些速度,请使用以下最佳做法:

  • 确保您的应用可生成足够的 I/O 操作

    如果您的应用生成的 IOPS 低于上述图表中描述的上限,则您将无法达到该 IOPS 水平。例如,在 500 GB 的磁盘上,预期的 IOPS 上限为 15000 IOPS。但是,如果生成的 IOPS 少于此值,或者 I/O 操作大于 8 KB,则不会达到 15000 IOPS。

  • 确保以足够的并行性提供 I/O 操作

    使用足够大的队列深度,您可以利用操作系统的并行性。如果您提供 1000 IOPS,但以队列深度为 1 的同步方式执行此操作,则所能达到的 IOPS 将远远低于图表中描述的上限。最低程度,您的应用应该为每 400-800 IOPS 提供 1 个队列深度。

  • 确保在生成 I/O 的实例上有足够的可用 CPU

    如果您的虚拟机实例缺乏 CPU,则您的应用将无法管理上述 IOPS。我们建议您为每 2000-2500 IOPS 的预期流量准备一个可用的 CPU。

  • 确保您的应用已针对大容量磁盘上合理的时态数据位置进行了优化

    如果您的应用在短时间内访问分布于某个磁盘不同部分的数据(每个 vCPU 数百 GB),则无法实现最佳 IOPS。如需获得最佳性能,请针对时态数据位置进行优化,并权衡各种因素(如磁盘碎片和磁盘被访问部分的随机性)。

  • 确保对操作系统中的 I/O 调度程序进行配置以满足您的特定需求

    在基于 Linux 的系统上,您可以将 I/O 调度程序设置为 noop,以在基于 SSD 的设备上实现最大 IOPS。

对 SSD 永久性磁盘的性能进行基准化分析

以下命令假设有一个 2500 GB 容量的 PD-SSD 设备。如果您设备的容量大小不同,请修改 --filesize 参数的值。此磁盘大小是实现 32 个 vCPU 虚拟机吞吐量限制所必需的。

    # Install dependencies
    sudo apt-get update
    sudo apt-get install -y fio
  1. 使用非零数据填充磁盘。对于永久性磁盘而言,从空白的磁盘块读取内容的延迟配置文件与包含数据的磁盘块不同。我们建议您在运行任何读取延迟基准化分析之前先填充磁盘。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=fill_disk \
      --filename=/dev/sdb --filesize=2500G \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=128K --iodepth=64 --rw=randwrite
    
  2. 使用具有多个(8 个或更多)并行数据流(I/O 大小为 1 MB,I/O 深度大于或等于 64)的顺序写入来测试写入带宽。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=write --numjobs=8 --offset_increment=100G
    
  3. 测试写入 IOPS。如需达到永久性磁盘的 IOPS 上限,您必须维护一个较深的 I/O 队列。例如,如果写入延迟时间为 1 毫秒,则对于每个正在执行的 I/O,虚拟机最多可以达到 1000 IOPS。如需达到 15000 IOPS,虚拟机必须维护至少 15 个正在执行的 I/O。如果您的磁盘和虚拟机能够达到 30000 IOPS,则正在执行的 I/O 数量必须至少有 30 个。如果 I/O 大小超过 4 KB,则虚拟机在达到 IOPS 上限之前可能会先达到带宽上限。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=64 --rw=randwrite
    
  4. 测试写入延迟时间。在测试 I/O 延迟时间时,请务必不要让虚拟机达到带宽或 IOPS 上限,否则观察到的延迟时间将无法反映出实际的永久性磁盘 I/O 延迟时间。例如:如果在 I/O 深度为 30 时达到了 IOPS 上限,并且 fio 命令已将其加倍,则总 IOPS 将保持不变,并且所报告的 I/O 延迟时间将加倍。

    # Running this command causes data loss on the second device.
    # We strongly recommend using a throwaway VM and disk.
    sudo fio --name=write_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randwrite
    
  5. 使用具有多个(8 个或更多)并行数据流(I/O 大小为 1 MB,I/O 深度等于 64 或更大)的顺序读取来测试读取带宽。

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=1M --iodepth=64 --rw=read --numjobs=8 --offset_increment=100G
    
  6. 测试读取 IOPS。如需达到永久性磁盘的 IOPS 上限,您必须维护一个较深的 I/O 队列。例如,如果 I/O 大小超过 4 KB,则虚拟机在达到 IOPS 上限之前可能会先达到带宽上限。

    sudo fio --name=read_iops_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=64 --rw=randread
    
  7. 测试读取延迟时间。请务必用数据填充磁盘,以获得真实的延迟时间测量结果。在此测试期间,请确保不要让虚拟机达到 IOPS 或吞吐量上限,因为一旦永久性磁盘达到其饱和上限,它将拒绝传入的 I/O,这将反映为 I/O 延迟时间的人为增加。

    sudo fio --name=read_latency_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --bs=4K --iodepth=4 --rw=randread
    
  8. 测试顺序读取带宽。

    sudo fio --name=read_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=read
    
  9. 测试顺序写入带宽。

    sudo fio --name=write_bandwidth_test \
      --filename=/dev/sdb --filesize=2500G \
      --time_based --ramp_time=2s --runtime=1m \
      --ioengine=libaio --direct=1 --verify=0 --randrepeat=0 \
      --numjobs=4 --thread --offset_increment=500G \
      --bs=1M --iodepth=64 --rw=write
    

优化本地 SSD

各种磁盘类型的性能图表中描述了本地 SSD 设备可实现的性能上限。如需优化应用和虚拟机实例以达到这些速度,请使用以下最佳做法:

对本地 SSD 使用访客环境优化功能

默认情况下,大多数由 Compute Engine 提供的 Linux 映像将自动运行一个优化脚本,该脚本会对实例进行配置以实现本地 SSD 的最大性能。该脚本会启用某些队列 sysfs 设置(用于增强机器的整体性能),并屏蔽对某些特定虚拟 CPU (vCPU) 的中断请求 (IRQ)。此脚本只针对 Compute Engine 本地 SSD 设备进行性能优化。

Ubuntu、SLES 和其他较旧的映像可能未配置为包含此性能优化功能。如果您使用的是这些映像中的任何一个或 v20141218 之前的映像,则可以安装访客环境来启用这些优化功能。

为 NVMe 或 SCSI 接口选择最佳映像

本地 SSD 在采用 NVMe 或 SCSI 接口时运行得最好,具体取决于您使用的操作系统。 为您的本地 SSD 设备选择一个最适合您的启动磁盘映像的接口。如果您的实例使用 SCSI 接口连接到本地 SSD,则可以在访客操作系统上启用多队列 SCSI,以通过 SCSI 接口实现最佳性能。

在具有自定义映像和本地 SSD 的实例上启用多队列 SCSI

某些公开映像可支持多队列 SCSI。如果您需要在导入到项目中的自定义映像上具备多队列 SCSI 功能,则必须自行启用该功能。只有包含内核版本 3.19 或更高版本的导入的 Linux 映像才能使用多队列 SCSI。

如需在某个自定义映像上启用多队列 SCSI,请在启用了 VIRTIO_SCSI_MULTIQUEUE 访客操作系统功能的情况下导入该映像,并向 GRUB 配置文件中添加一个条目:

CentOS

仅适用于 CentOS 7。

  1. 使用 API 导入您的自定义映像,并添加一个 type 值为 VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 项。

  2. 使用您的自定义映像创建一个实例,并挂接一个或多个本地 SSD

  3. 通过 SSH 连接到您的实例

  4. 查看 /sys/module/scsi_mod/parameters/use_blk_mq 文件的值。

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    如果此文件的值为 Y,则说明在导入的映像上已启用多队列 SCSI。如果此文件的值为 N,请在 GRUB 配置文件内的 GRUB_CMDLINE_LINUX 条目中添加 scsi_mod.use_blk_mq=Y,并重启系统。

    1. 在文本编辑器中打开 /etc/default/grub GRUB 配置文件。

      $ sudo vi /etc/default/grub
      
    2. scsi_mod.use_blk_mq=Y 添加到 GRUB_CMDLINE_LINUX 条目中。

      GRUB_CMDLINE_LINUX=" vconsole.keymap=us console=ttyS0,38400n8 vconsole.font=latarcyrheb-sun16 scsi_mod.use_blk_mq=Y"
      
    3. 保存配置文件。

    4. 运行 grub2-mkconfig 命令即可重新生成 GRUB 文件并完成配置。

      $ sudo grub2-mkconfig -o /boot/grub2/grub.cfg
      
    5. 重启实例。

      $ sudo reboot
      

Ubuntu

  1. 使用 API 导入您的自定义映像,并添加一个 type 值为 VIRTIO_SCSI_MULTIQUEUEguestOsFeatures 项。

  2. 使用您的自定义映像创建一个实例,并使用 SCSI 接口附加一个或多个本地 SSD

  3. 通过 SSH 连接到您的实例

  4. 查看 /sys/module/scsi_mod/parameters/use_blk_mq 文件的值。

    $ cat /sys/module/scsi_mod/parameters/use_blk_mq
    

    如果此文件的值为 Y,则说明在导入的映像上已启用多队列 SCSI。如果此文件的值为 N,请在 GRUB 配置文件内的 GRUB_CMDLINE_LINUX 条目中添加 scsi_mod.use_blk_mq=Y,并重启系统。

    1. 在文本编辑器中打开 sudo nano /etc/default/grub GRUB 配置文件。

      $ sudo nano /etc/default/grub
      
    2. scsi_mod.use_blk_mq=Y 添加到 GRUB_CMDLINE_LINUX 条目中。

      GRUB_CMDLINE_LINUX="scsi_mod.use_blk_mq=Y"
      
    3. 保存配置文件。

    4. 运行 update-grub 命令即可重新生成 GRUB 文件并完成配置。

      $ sudo update-grub
      
    5. 重启实例。

      $ sudo reboot
      

停用写入缓存刷新功能

文件系统、数据库和其他应用会使用缓存刷新功能来确保在各个检查点将数据提交到持久性存储系统中。对于大多数存储设备来说,这种默认操作是有意义的。但是,本地 SSD 上的写入缓存刷新速度相当缓慢。您可以通过在这些应用中停用自动刷新命令或通过在文件系统级别停用刷新选项来提高某些应用的写入性能。

无论您为文件系统和应用设置的刷新命令是怎样的,本地 SSD 总是会在两秒钟内刷新已缓存的写入内容,因此临时硬件故障最多只会导致您丢失两秒钟的缓存写入内容。无论是否已刷新数据,永久性的硬件故障仍可能导致设备上的所有数据丢失,因此您仍应将关键数据备份到永久性磁盘Cloud Storage 存储分区中。

如需在 ext4 文件系统上停用写入缓存刷新功能,请在您的装载选项或 /etc/fstab 条目中添加 nobarrier。例如:

$ sudo mount -o discard,defaults,nobarrier /dev/[LOCAL_SSD_ID] /mnt/disks/[MNT_DIR]

其中:[LOCAL_SSD_ID] 是您要装载的本地 SSD 的设备 ID,[MNT_DIR] 是要装载到的目录。

对本地 SSD 的性能进行基准化分析

“性能”部分中提供的本地 SSD 性能数据是通过在本地 SSD 实例上使用特定的设置而得到的。如果您的实例无法达到这些性能上限,并且您已经按照建议的本地 SSD 设置配置了实例,则可以通过复制 Compute Engine 团队所使用的设置,将您的性能上限与已发布的上限进行比较。

  1. 创建一个本地 SSD 实例,该实例针对每个设备具有四个或八个 vCPU,具体取决于您的工作负载。例如,如果您要将四个本地 SSD 设备附加到一个实例,请使用具有 16 或 32 个 vCPU 的机器类型。

    以下命令将创建一个具有 8 个 vCPU 和一个本地 SSD 的虚拟机:

    gcloud compute instances create ssd-test-instance \
    --machine-type "n1-standard-8" \
    --local-ssd interface="SCSI"
    
  2. 在您的虚拟机上运行以下脚本。该脚本将复制用于达到“性能”部分中提供的 SSD 性能数据的设置。请注意,--bs 参数定义了磁盘块的大小,此块大小会影响不同类型的读写操作的结果。

    # install dependencies
    sudo apt-get update -y
    sudo apt-get install -y build-essential git libtool gettext autoconf \
    libgconf2-dev libncurses5-dev python-dev fio bison autopoint
    
    # blkdiscard
    git clone https://git.kernel.org/pub/scm/utils/util-linux/util-linux.git
    cd util-linux/
    ./autogen.sh
    ./configure --disable-libblkid
    make
    sudo mv blkdiscard /usr/bin/
    sudo blkdiscard /dev/disk/by-id/google-local-ssd-0
    
    # full write pass - measures write bandwidth with 1M blocksize
    sudo fio --name=writefile --size=100G --filesize=100G \
    --filename=/dev/disk/by-id/google-local-ssd-0 --bs=1M --nrfiles=1 \
    --direct=1 --sync=0 --randrepeat=0 --rw=write --refill_buffers --end_fsync=1 \
    --iodepth=200 --ioengine=libaio
    
    # rand read - measures max read IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randread --blocksize=4k --group_reporting
    
    # rand write - measures max write IOPS with 4k blocks
    sudo fio --time_based --name=benchmark --size=100G --runtime=30 \
    --filename=/dev/disk/by-id/google-local-ssd-0 --ioengine=libaio --randrepeat=0 \
    --iodepth=128 --direct=1 --invalidate=1 --verify=0 --verify_fatal=0 \
    --numjobs=4 --rw=randwrite --blocksize=4k --group_reporting
    

后续步骤

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Compute Engine 文档