优化 Persistent Disk 性能


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

以下部分介绍了影响磁盘性能的虚拟机和工作负载特征,并讨论了一些可以调整以获得更好性能的关键元素。一些建议以及如何将其中一些建议应用于特定类型的工作负载。

影响磁盘性能的因素

以下部分介绍了会影响虚拟机的磁盘性能的因素。

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

虚拟机的网络出站流量上限取决于虚拟机的机器类型。

Compute Engine 通过多个并行写入将数据存储在永久性磁盘上,以确保内置冗余性。此外,每个写入请求都有一定的开销,因为占用了额外的写入带宽。

虚拟机实例可以发出的写入流量上限为网络出站流量上限除以考虑复制和开销的带宽系数。

对于通用计算优化存储优化内存优化加速器优化的机器系列,网络出站流量上限列在机器类型表的出站带宽上限 (Gbps) 列中。

在网络完全利用时,带宽系数约为 1.16 倍,这意味着写入的 16% 的字节是开销。对于区域级永久性磁盘,带宽系数约为 2.32 倍,以应对额外的复制开销。

在永久性磁盘读写操作与网络出站流量带宽争用的情况下,系统会将机器类型定义的网络出站流量带宽上限的 60% 分配给永久性磁盘写入。剩余 40% 可用于所有其他网络出站流量。如需详细了解其他网络出站流量,请参阅出站流量带宽

以下示例显示了如何计算 N1 虚拟机实例上永久性磁盘的最大写入带宽。带宽分配是分配给永久性磁盘的网络出站流量带宽的一部分。最大写入带宽是针对开销调整的永久性磁盘的最大写入带宽。

虚拟机的 vCPU 数量 网络出站流量上限(MB/秒) 带宽分配(MB/秒) 最大写入带宽(MB/秒) 完整网络利用率时的最大写入带宽(MB/秒)
1 250 150 216 129
2-7 1,250 750 1,078 647
8-15 2,000 1,200 1,724 1,034
16+ 4000 2400 3,448 2,069

您可以使用以下公式计算永久性磁盘带宽上限:

具有 1 个 vCPU 的 N1 虚拟机

网络出站流量上限如下:

2 Gbps / 8 位 = 0.25 GB/秒 = 250 MB/秒

网络充分利用时永久性磁盘的带宽分配为:

250 MB/秒 * 0.6 = 150 MB/秒。

无网络争用的永久性磁盘的最大写入带宽为:

  • 可用区级磁盘:250 MB/秒 / 1.16 ~= 216 MB/秒
  • 区域级磁盘:250 MB/秒 / 2.32 ~= 108 MB/秒

网络充分利用时永久性磁盘的最大写入带宽为:

  • 可用区级磁盘:150 MB/秒 / 1.16 ~= 129 MB/秒
  • 区域级磁盘:150 MB/秒 / 2.32 ~= 65 MB/秒

网络出站流量限制提供了性能上限。其他因素可能会限制低于此水平的性能。如需了解其他性能限制条件,请参阅以下部分。

同时读取和写入

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

永久性磁盘卷无法同时达到其读取和写入操作的吞吐量和 IOPS 上限。

吞吐量的计算方法是 IOPS * I/O size。为充分利用 SSD 永久性磁盘上同时读取和写入的吞吐量上限,请使用不会让读取和写入 IOPS 总和超过 IOPS 上限的 I/O 大小。

下表列出了每个虚拟机同时读取和写入的 IOPS 限制。

标准永久性磁盘 SSD 永久性磁盘(8 个 vCPU) SSD 永久性磁盘(32 个或更多 vCPU) SSD 永久性磁盘(64 个或更多 vCPU)
读取 写入 读取 写入 读取 写入 读取 写入
7500 0 15,000 0 60,000 0 100000 0
5625 3750 11250 3750 45000 15,000 75000 25,000
3750 7500 7500 7500 30000 30000 50,000 50,000
1875 11250 3750 11250 15,000 45000 25,000 75000
0 15,000 0 15,000 0 60,000 0 100000

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

下表列出了每个虚拟机同时读取和写入的吞吐量限制(MB/秒)。

标准永久性磁盘 SSD 永久性磁盘(6-14 个 vCPU) SSD 永久性磁盘(16 个或更多 vCPU)
读取 写入 读取 写入 读取 写入
1200 0 800* 800* 1,200* 1,200*
900 100
600 200
300 300
0 400

* 对于 SSD 永久性磁盘,读取吞吐量最大值和写入吞吐量最大值彼此独立,因此这些上限是不变的。

逻辑卷大小

永久性磁盘的大小最大可达 64 TiB,您可以使用虚拟机内的逻辑卷管理创建最大 257 TiB 的单个逻辑卷。较大的卷大小可通过以下方式影响性能:

  • 在这种量级上,并非所有本地文件系统都能保持运行良好。装载和文件系统检查等常见操作所需的时间可能超出预期。
  • 在磁盘容量较小时,永久性磁盘可以达到性能上限。在一个虚拟机有如此之多的存储容量时,磁盘完整读取或写入所需的时间更长。如果您的应用有相应支持,请考虑适用多个虚拟机,以提高整个系统的吞吐量。
  • 截取大量永久性磁盘的快照所需的时间可能超出预期,如果没有仔细与您的应用协调配合,还可能会导致逻辑卷的视图不一致。

将多个磁盘挂接到单个虚拟机实例

将多个磁盘挂接到虚拟机时,磁盘的性能限制取决于磁盘是同一类型还是不同类型。

相同类型的多个磁盘

如果您有多个类型相同的磁盘以同一模式(例如,读取/写入)挂接到一个虚拟机实例,则这些磁盘的性能限制与具有这些磁盘总大小的单个磁盘的限制相同。如果您 100% 使用所有磁盘,则无论相对磁盘大小如何,都会在磁盘间平均分配总体性能限制。

例如,假设您有一个 200 GB 的 pd-standard 磁盘和一个 1000 GB 的 pd-standard 磁盘。如果您不使用 1000 GB 的磁盘,则 200 GB 的磁盘可达到 1200 GB 的标准磁盘的性能限制。如果 100% 使用这两个磁盘,则每个磁盘的性能限制为 600 GB 的 pd-standard 磁盘(1200 GB/2 个磁盘 = 600 GB 的磁盘)。

不同类型的多个磁盘

如果您将不同类型的磁盘挂接到虚拟机,则最大可能的性能会达到虚拟机支持的最快速磁盘的性能限制。挂接的磁盘的累计性能不会超过虚拟机支持的最快速磁盘的性能限制。

针对面向 IOPS 或吞吐量的工作负载优化磁盘

性能建议取决于您是希望最大限度地提高 IOPS 还是吞吐量。

面向 IOPS 的工作负载

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

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

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

  • 如果适用于您的虚拟机机器类型,请使用 Google Cloud Hyperdisk Extreme 磁盘,它使您能够更改预配的 IOPS。

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

面向吞吐量的工作负载

流式传输操作(例如 Hadoop 作业)可受益于快速顺序读取,而较大的 I/O 大小可以提高流式传输的性能。

  • 使用 256 KB 或更大的 I/O 大小。

  • 如果适用于您的虚拟机机器类型,请使用 Hyperdisk 吞吐量磁盘,这使您能够更改预配的吞吐量。

  • 对于标准永久性磁盘,请尽可能使用 8 个或更多并行序列 I/O 流。标准永久性磁盘旨在采用与物理 HDD 硬盘相似的方式优化顺序磁盘访问的 I/O 性能。

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

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

  • 对于 SSD 永久性磁盘,请确保操作系统中的 I/O 调度器配置为满足您的特定需求。

    在基于 Linux 的系统上,检查 I/O 调度器是否设置为 none。此 I/O 调度器不会对请求进行重新排序,因此非常适合快速随机 I/O 设备。

    1. 在命令行中,验证您的 Linux 机器使用的 I/O 调度器:

      cat /sys/block/sda/queue/scheduler
      

      输出类似于以下内容:

      [mq-deadline] none
      

      当前处于活动状态的 I/O 调度器显示在方括号 ([]) 中。

    2. 如果您的 I/O 调度器未设置为 none,请执行以下步骤之一:

      • 如需将默认 I/O 调度器更改为 none,请在 GRUB 配置文件的 GRUB_CMDLINE_LINUX 条目中设置 elevator=none。此文件通常位于 /etc/default/grub 中,但在一些早期发行版中,它可能位于其他目录中。
      GRUB_CMDLINE_LINUX="elevator=none vconsole.keymap=us console=ttyS0,38400n8 vconsole.font=latarcyrheb-sun16
      

      更新 GRUB 配置文件后,在系统上配置引导加载程序,以使它能够在 Compute Engine 上启动。

      • 或者,您可以在运行时更改 I/O 调度器:
      echo 'none' > sudo /sys/block/sda/queue/scheduler
      

      如果您使用此方法,系统会在重新启动时切换回默认 I/O 调度器。再次运行 cat 命令以验证您的 I/O 调度器。

可以提高磁盘性能的工作负载变化

某些工作负载行为可以提高挂接磁盘上的 I/O 操作的性能。

使用较高的 I/O 队列深度

与本地挂接的磁盘(例如本地 SSD 磁盘)相比,永久性磁盘的延迟时间更高,因为它们是网络附加设备。它们可以提供非常高的 IOPS 和吞吐量,但您必须确保能够并行完成足够多的 I/O 请求。并行完成的 I/O 请求数称为 I/O 队列深度

下表显示建议的 I/O 队列深度,以确保您可以达到特定的性能级别。请注意,下表对典型延迟时间略微高估,以显示保守的建议。该示例假定您使用的是 16 KB 的 I/O 大小。

使用较大的 I/O 大小生成足够的 I/O

  • 使用较大的 I/O 大小

    为了确保 IOPS 限制和延迟不会成为您应用性能的瓶颈,请保证 I/O 大小至少为 256 KB。

    为分布式文件系统应用使用较大的条带大小使用较大条带大小(4 MB 或更大)的随机 I/O 工作负载在标准永久性磁盘上可实现出色的性能,因为此时,工作负载会更像是多个顺序流式磁盘访问。

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

    确保您的应用可生成足够的 I/O,以充分利用磁盘的 IOPS 和吞吐量限制。在 Cloud Monitoring 中查看持久性磁盘使用情况和性能指标,以更好地了解您的工作负载 I/O 模式。

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

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

将高 I/O 负载限制在 span 最大值范围内

span 是指单个物理磁盘上连续的逻辑块地址范围。当限制为特定的 span 最大值时,高 I/O 负载可实现最高性能,而这个最大值具体取决于磁盘所挂接的虚拟机的机器类型,如下表所列。

机器类型 推荐的 Span 最大值
  • m2-megamem-416
  • C2D 虚拟机
25 TB
所有其他机器类型 50 TB

为了性能目的,不同永久性磁盘的 span 相加为 50 TB 或以内可以视为等同于单个 span 为 50 TB。

操作系统更改以提升磁盘性能

在某些情况下,您可以在操作系统级层启用或停用功能,或以特定方式配置挂接的磁盘来提高磁盘性能。

避免在 Linux 中使用 ext3 文件系统

在 Linux 虚拟机中使用 ext3 文件系统可能会导致写入负载繁重时性能下降。应尽可能使用 ext4。ext4 文件系统驱动程序向后兼容 ext3/ext2,并支持装载 ext3 文件系统。ext4 文件系统是大多数 Linux 操作系统上的默认文件系统。

如果您无法迁移到 ext4,一种解决方法是使用 data=journal 装载选项来装载 ext3 文件系统。这有助于提高写入 IOPS,不过会牺牲一定的写入吞吐量。迁移到 ext4 后,某些基准性能可提高 7 倍之多。

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

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

在大多数 Linux 操作系统上,您可以在将某个永久性磁盘装载到虚拟机时启用 DISCARD。默认情况下,当您装载永久性磁盘时,Windows Server 2012 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 操作。不过,您可以选择定期运行 fstrim,作为 DISCARD 操作的补充,或取代该操作。如果您不使用 DISCARD 操作,请在创建启动磁盘快照之前运行 fstrim。裁剪文件系统可让您创建的快照映像更小,从而减少存储快照的费用。

调整 readahead 值

为了提高 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

修改虚拟机或创建新虚拟机

每种虚拟机类型都存在一些限制,这些限制会影响您从挂接的磁盘获得的性能。这些限值包括:

  • 永久性磁盘性能随着可用 vCPU 数量的增加而提升。
  • 并非所有机器类型都支持 Hyperdisk。
  • 网络出站流量费率会随着可用 vCPU 的数量增加而增加。

确保您的 CPU 有空闲时间

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

如需增加虚拟机可用的 vCPU 数量,您可以创建新虚拟机,也可以修改虚拟机实例的机器类型

创建新虚拟机以获取新功能

并非所有机器类型或机器类型都支持新的磁盘类型。Hyperdisk 可为工作负载提供更高的 IOPS 或吞吐率,但目前仅适用于少数机器系列,并且至少需要 64 个 vCPU。

新的虚拟机机器系列通常在较新的 CPU 上运行,可以比之前的 CPU 提供更好的性能。另外,较新的 CPU 还支持其他功能来提升工作负载的性能,例如高级矩阵扩展 (AMX) 或 Intel 高级矢量扩展 (AVX-512)。

后续步骤