红帽 OpenShift 虚拟化 4.19 显著提升了数据库等 I/O 密集型工作负载的性能和速度。红帽 OpenShift 虚拟化的多 I/O 线程是一项新功能,允许将虚拟机(VM)磁盘 I/O 分散到主机上的多个工作线程中,然后将这些线程映射到虚拟机内的磁盘队列。这使得虚拟机能够高效地将 vCPU 和主机 CPU 用于多流 I/O,从而提高性能。

本文是我同事 Jenfer Abrams 撰写的功能简介的姊妹篇。在本文中,我将提供性能测试结果,以帮助您调优虚拟机,从而实现更高的 I/O 吞吐量。

为了进行测试,我使用 fio 在 Linux 虚拟机上对合成 I/O 工作负载进行了基准测试。目前正在推进其他测试工作,包括应用测试以及在 Microsoft Windows 平台上的测试。

有关如何在基于内核的虚拟机(KVM)中实施此功能的更多背景信息,请参阅这篇关于 IO 线程虚拟队列映射的文章,以及另一篇姊妹文章,该文章展示了在红帽企业 Linux(RHEL)环境中运行的虚拟机中,数据库工作负载的性能改进。 

测试说明

我测试了两种配置下的 I/O 吞吐量: 

  1. 使用本地存储 Operator(LSO)置备的逻辑卷管理器实现本地存储的集群
  2. 使用 OpenShift 数据基础(ODF)的单独集群 

这些配置之间差异非常大,无法进行比较。

我们在 pod(作为基准)和虚拟机上进行了测试。虚拟机配置为 16 个核心和 8GB 内存。测试过程中采用了 512GB 测试文件(一个虚拟机)和 256GB 测试文件(2 个虚拟机)。所有测试均使用直接 I/O。对于虚拟机,使用块模式且格式化为 ext4 的持久卷声明(PVC);对于 pod,使用了同样格式化为 ext4 的文件系统模式 PVC。所有测试均通过 libaio I/O 引擎运行。

我测试了以下参数组合:

参数

设置

存储卷类型

本地(LSO)、ODF

Pod/虚拟机数量

1、2

I/O 线程数量(仅虚拟机)

无(基准)、1、2、3、4、6、8、12、16

I/O 操作

顺序和随机读取与写入

I/O 块大小(字节)

2K、4K、32K、1M

并发作业数量

1、4、16

I/O iodepth(iodepth)

1、4、16

我使用 ClusterBuster 来编排测试。虚拟机使用 CentOS Stream 9,pod 同样使用 CentOS Stream 作为容器镜像基础。

本地存储

本地存储集群是一个 5 节点(3 个主节点 + 2 个工作节点)集群,由包含 2 个 Intel Xeon Gold 6130 CPU 的 Dell R740xd 节点组成,每个节点都有 16 个核心和 2 个线程(32 个 CPU),因此总计 32 个核心和 64 个 CPU。每个节点包含 192GB RAM。I/O 子系统由四个戴尔品牌的 Kioxia CM6 MU 1.6 TB NVMe 驱动器组成,这些驱动器采用默认设置的 RAID0 条带化多设备(MD)配置。持久卷声明是使用 lvmcluster operator 从此 MD 中划分出来的。遗憾的是,我目前仅能使用这种相对保守的配置进行测试,若采用更快的 I/O 系统,多 I/O 线程很可能会带来更显著的性能提升。

OpenShift 数据基础 

OpenShift 数据基础(ODF)集群是一个 6 节点(3 个主节点 + 3 个工作节点)集群,由包含 2 个 AMD EPYC 9534 CPU 的 Dell PowerEdge R7625 节点组成,每个节点都有 64 个核心和 2 个线程(128 个 CPU),因此总计 128 个核心和 256 个 CPU。每个节点包含 512GB RAM。I/O 子系统配置为每个节点两个 5.8TB NVMe 驱动器,通过 25 GbE 默认 pod 网络进行三向复制。本次测试未采用较快速的网络,但若采用较新的网络硬件,预计可获得更显著的性能提升。

结果摘要

此测试针对具有特定 I/O 后端的多 I/O 线程进行了评估,结果可能不适用于您的用例。存储特征方面的差异,可能会对 I/O 线程数量的选择产生重大影响。

以下是我获得的测试结果。

  • 最大 I/O 吞吐量:对于本地存储,pod 和虚拟机的最大读取和写入吞吐量分别约为每秒 7.3GB 和每秒 6.7GB,无论 iodepth 或本地存储上的作业数量如何。该数值远低于硬件预期性能。这些设备(每个具有 4 条 PCIe gen4 通道)标称读取速度为每秒 6.9GB,写入速度为每秒 4.2MB。虽然未深究具体原因,但测试是在过时的硬件上运行的,这可能会造成一定的影响。当前峰值性能明显优于单个驱动器的性能,证明条带化配置确实发挥了作用。对于 ODF,我们实现的最佳读取速度约为每秒 5GB,最佳写入速度约为每秒 2GB。
  • 大块 I/O(1MB)几乎没有提升效果,因为性能已受到系统的限制。
  • 最佳的 I/O 线程数量因工作负载和存储特征而异。正如预期的那样,没有大量 I/O 并发的工作负载几乎未见改善。
    • 本地存储:对于具有大量 I/O 并发的虚拟机,建议一开始将线程数量设置为 4-8 个。尤其是对于 I/O 块大小较小和存在大量并发的工作负载,增加线程数量往往能带来更显著的性能提升。
    • ODF:使用超过 1 个 I/O 线程通常难以带来显著的性能提升,许多情况下甚至完全不需要。这可能是由于 pod 网络相对较慢造成的限制;若采用较快的网络连接,可能会产生不同的结果。
  • 与深度异步 I/O 相比,多 I/O 线程在多个并发作业场景下更能有效提升性能,至少在本测试中如此。
  • 在达到底层聚合最大 I/O 吞吐量(如上所述)之前,运行 1 个和 2 个并发虚拟机的性能表现几乎没有差异。
  • 在作业数量或 I/O iodepth 较低的情况下,多 I/O 线程未能完全缩小与 Pod 的性能差距。当 I/O iodepth 较高且操作规模较小时,虚拟机在写入操作方面的实际表现显著超越了 pod。

数字证明一切

以下是我在本地存储系统上使用多 I/O 线程所获得的整体 I/O 吞吐量。如您所见,当工作负载涉及较小的 I/O 块大小且需要高度并行快速 I/O 系统时,多 I/O 线程可带来显著优势。下面我将详细介绍不同数量的 I/O 线程所带来的效益。我注意到当采用 1MB 块大小时性能提升效果微乎其微,因为此时性能已经非常接近底层系统的限制。若采用更快的硬件,即使块大小较大,增加 I/O 线程仍可能会带来性能提升。

相较于虚拟机基准,增加 I/O 线程所能实现的最佳性能提升效果

(本地存储)

 

作业

iodepth

       
  

1

  

4

  

16

  

大小

操作

1

4

16

1

4

16

1

4

16

2048

随机读取

18%

31%

30%

30%

103%

192%

151%

432%

494%

 

随机写入

81%

59%

24%

153%

199%

187%

458%

433%

353%

 

读取

67%

58%

25%

64%

71%

103%

252%

241%

287%

 

写入

103%

64%

0%

143%

99%

84%

410%

250%

203%

2048(总计)

 

67%

53%

20%

97%

118%

141%

318%

339%

334%

4096

随机读取

18%

34%

28%

33%

101%

208%

156%

432%

492%

 

随机写入

95%

69%

20%

149%

200%

187%

471%

543%

481%

 

读取

26%

53%

27%

24%

46%

66%

142%

155%

165%

 

写入

103%

69%

0%

144%

86%

48%

438%

256%

161%

4096(总计)

 

60%

56%

19%

87%

108%

127%

302%

346%

325%

32768

随机读取

16%

23%

26%

23%

71%

124%

99%

160%

129%

 

随机写入

75%

71%

28%

108%

132%

116%

203%

123%

115%

 

读取

21%

57%

25%

21%

42%

32%

77%

54%

32%

 

写入

79%

64%

26%

104%

59%

24%

195%

45%

27%

32768(总计)

 

48%

53%

26%

64%

76%

74%

143%

96%

76%

1048576

随机读取

5%

2%

0%

9%

0%

0%

17%

0%

0%

 

随机写入

10%

0%

1%

6%

0%

2%

9%

0%

2%

 

读取

12%

18%

0%

9%

0%

0%

16%

0%

0%

 

写入

19%

0%

0%

7%

0%

0%

9%

0%

0%

1048576(总计)

 

11%

5%

0%

8%

0%

1%

13%

0%

0%

 

以下是为达到最多 16 个 I/O 线程可实现的最佳结果的 90%,所需的 I/O 线程数量。例如,如果我在测试中通过操作、块大小、作业数量和 iodepth 的特定组合所获得的最佳结果是 1GB/秒,那么此处的指标就是达到 900MB/秒所需的最少线程数量。这使得在设定保守的线程数量时,仍能获得良好的性能表现。

实现 90% 的最佳性能所需的最少 iothread 数量

(本地存储)

 

作业

iodepth

       
  

1

  

4

  

16

  

大小

操作

1

4

16

1

4

16

1

4

16

2048

随机读取

1

1

1

1

4

8

3

12

12

 

随机写入

1

1

1

3

16

12

8

12

12

 

读取

1

1

1

1

4

4

4

6

8

 

写入

1

1

0

2

12

6

8

6

6

2048(总计)

 

1

1

1

2

9

8

6

9

10

4096

随机读取

1

1

1

1

4

8

3

12

12

 

随机写入

1

1

1

3

16

12

8

12

12

 

读取

1

1

1

1

2

3

3

6

8

 

写入

1

1

0

3

12

4

8

6

4

4096(总计)

 

1

1

1

2

9

7

6

9

9

32768

随机读取

1

1

1

1

3

6

2

4

3

 

随机写入

1

1

1

2

12

6

4

3

3

 

读取

1

1

1

1

2

2

2

2

2

 

写入

1

1

1

2

6

2

4

2

1

32768(总计)

 

1

1

1

2

6

4

3

3

2

1048576

随机读取

0

0

0

0

0

0

1

0

0

 

随机写入

0

0

0

0

0

0

0

0

0

 

读取

1

1

0

0

0

0

1

0

0

 

写入

1

0

0

0

0

0

0

0

0

1048576(总计)

 

1

0

0

0

0

0

1

0

0

详细结果

对于衡量的每个测试案例,我计算了以下性能指标:

  1. I/O 吞吐量衡量
  2. 最佳虚拟机性能(未直接报告)
  3. 达到最佳虚拟机性能的 90% 所需的最低 I/O 线程数量
  4. 最佳虚拟机性能与 pod 性能之间的比率
  5. 最佳虚拟机性能相对于基准虚拟机性能的提升幅度

我并未报告最佳性能对应的线程数量,因为在多数情况下,差异微乎其微,甚至小于报告 I/O 性能时的正常波动范围。

鉴于本地存储与 ODF 之间的特征差异明显,我分别提供了两者的结果总结。

下面所有性能图表均显示了以下对象的测试结果:容器集(pod)、未使用 I/O 线程(0)的基准虚拟机以及 X 轴上标注的指定数量的 I/O 线程。

本地存储

如果我们注意观察原始性能数据,就会发现至少在某些情况下,使用多 I/O 线程可带来显著效益。例如,在 16 个作业、iodepth 为 1的异步 I/O 场景下,在本地存储中使用额外的 I/O 线程可带来近一个数量级的性能提升:

Threads for OpenShift

即使仅使用单个流 I/O,使用额外的 I/O 线程也能实现性能提升。不出所料,多个线程并不会带来助益:

Threads for OpenShift

在某些异常情况下,额外的 I/O 线程实际上还会损害性能。在这种情况下,使用块大小较小的深度异步 I/O 时,未配置专用 I/O 线程的虚拟机反而能实现最佳性能(甚至优于 pod)。目前尚未查明此现象的具体原因。

Threads for OpenShift

所有这些都表明,要充分发挥多 I/O 线程的最佳性能,您需要针对特定工作负载进行实验。

ODF 集群结果

ODF 与本地存储不同,本地存储在使用多 I/O 线程时,小块随机写入性能显著提升;而我观察到即使在作业量较高的情况下,ODF 的性能提升也微乎其微。更快的网络或更低的网络延迟可能会带来更大的效益。读取操作(尤其是随机读取)确实显示出适度性能提升,但写入操作以及低作业量场景几乎未见(如果有的话)性能改善。

Threads for OpenShift

结论

OpenShift 虚拟化的多 I/O 线程是 OpenShift 4.19 中一项激动人心的新功能,可为具有并发 I/O 的工作负载带来显著的 I/O 性能提升,尤其是在快速 I/O 系统(如我在测试中使用的本地 NVMe 存储)中。通过采用更快的 I/O 子系统,有望从多 I/O 线程中获得更多效益,因为需要更多 CPU 才能充分驱动底层裸机 I/O。与以往的 I/O 一样,I/O 系统和整体工作负载之间的差异会显著影响性能表现,因此我建议您针对自身工作负载进行测试,以充分利用这项新功能。希望我的测试结果能帮助您针对 I/O 线程做出正确的选择!

产品试用

红帽 OpenShift 虚拟化引擎 | 产品试用

专门用于部署、管理和扩展虚拟机的精简解决方案。

关于作者

UI_Icon-Red_Hat-Close-A-Black-RGB

按频道浏览

automation icon

自动化

有关技术、团队和环境 IT 自动化的最新信息

AI icon

人工智能

平台更新使客户可以在任何地方运行人工智能工作负载

open hybrid cloud icon

开放混合云

了解我们如何利用混合云构建更灵活的未来

security icon

安全防护

有关我们如何跨环境和技术减少风险的最新信息

edge icon

边缘计算

简化边缘运维的平台更新

Infrastructure icon

基础架构

全球领先企业 Linux 平台的最新动态

application development icon

应用领域

我们针对最严峻的应用挑战的解决方案

Virtualization icon

虚拟化

适用于您的本地或跨云工作负载的企业虚拟化的未来