此测试的目的是展示使用 INTEL SSDPEYKX040T8 NVMe 驱动器在 Ceph 集群(特别是 CephFS)中可实现的最大性能。为避免指控供应商作弊,使用行业标准 IO500 基准测试来评估整个存储设置的性能。
剧透:尽管只使用了 5 节点的 Ceph 集群,因此无法正式提交结果(至少需要 10 个节点),但获得的基准分数已经足以进入最佳列表的前 40 名-执行 2019 年的 10 节点存储系统。
向 croit 提供了一个由连接到 100Gbps 网络的七台 Supermicro 服务器组成的实验室。其中六台服务器具有以下规格:
此外,还有一台具有不同配置的服务器:
在所有服务器上,板载网络仅用于 IPMI 和管理目的。在每个 Mellanox 网卡的两个 100Gbe 端口中,只有一个使用直连铜缆连接到运行 Cumulus Linux 4.2 的 SSE-C3632S 交换机。
在测试期间,SSG-1029P-NMR36L 服务器被用作 croit 管理服务器,并作为运行基准测试的主机。由于(正确地)怀疑单个 100Gbps 链路不足以揭示集群的性能,因此其中一台 SSG-1029P-NES32R 服务器也专用于客户端角色。在这两台服务器上,都安装了 Debian 10.5。内核是从 Debian “backports” 存储库安装的,以便获得 cephfs 客户端的最新改进。
其余五台 SSG-1029P-NES32R 服务器用于 Ceph 集群(使用 Ceph 14.2.9),方法是从管理节点对它们进行网络引导。内核版本是 4.19。
五台服务器参与了 Ceph 集群。在三台服务器上,小型 SATA SSD 用于 MON 磁盘。在每个 NVMe 驱动器上,都创建了一个 OSD。在每台服务器上,都配置了一个 MDS(负责 cephfs 元数据操作的 Ceph 组件)。为了尽可能并行化元数据操作(即在基准测试的“简单”部分),四个 MDS 服务器被标记为活动的,其余的一个作为备用服务器。应该注意的是,具有多个活动 MDS 服务器的配置是否适用于生产 Ceph 集群仍然存在争议。
在客户端节点上,使用了内核 cephfs 客户端,通过 /etc/fstab 中的这一行:
:/ /mnt/cephfs ceph name=admin,_netdev 0 0
所有客户端和服务器都在一个 L2 网段,网络为 10.10.49.0/24。设置了无密码 ssh,因为这是 OpenMPI 的要求,IO500 基准测试使用 OpenMPI 以并行和分布式方式运行工作程序。
最初,打算将基准测试结果与每个节点有 6 个 OSD 的另一个 Ceph 集群进行比较。因此,每个主机上的两个 NVMe 驱动器通过为它们分配一个单独的设备类而被搁置一旁。然而,这一意图从未实现。尽管如此,大多数基准测试都是在每个节点仅使用 6 个 NVMe OSD 完成的。
可用存储分为三个池:cephfs_metadata(64 个 PG)、cephfs_data(512 个 PG)和 rbd_benchmark(也是 512 个 PG)。因此,虽然每个 OSD 的 PG 总数接近理想值,但 cephfs 使用的数据池中的 PG 数量少于本例中通常使用的 PG 数量(即 1024)。这里的理论是太少的 PG 会导致数据不平衡(我们并不真正关心),而太多的 PG 可能会产生性能问题。
IO500 是由 Virtual Institute for I/O 管理的存储基准。它测量不同场景下基于集群的文件系统的带宽和 IOPS 数据,并将最终分数作为在所有测试阶段获得的性能指标的几何平均值得出。在每个阶段,执行“ior”工具(用于带宽测试)或“mdtest”工具(用于测试各种元数据操作的性能)的多个副本,并将结果合并。还有一个基于并行“查找”类程序的阶段。作为实现细节,MPI 用于编排。
执行阶段的顺序以这样一种方式组织,即基于 ior 和基于 mdtest 的阶段大多相互交错。
带宽测试是使用“ior”工具完成的。有两个“难度”级别(简单和困难),对于每个级别,带宽都是针对写入和单独的读取来测量的。基准测试结束时报告的带宽数字是所有四个测试的几何平均值。
默认情况下,两个难度级别的写入时间为 5 分钟,使用 POSIX 原语进行文件系统访问。在简单模式下,每个 ior 进程使用一个文件,写入按顺序完成,传输大小为 256 KiB。在硬模式下,所有进程写入同一文件的交错部分,使用奇怪的 47008 字节传输大小和“跳跃”线性访问(lseek() 对其他进程要写入的字节,写入 47008 字节,重复循环)。在这两种情况下,每个进程最后只执行一次 fsync() 调用,即,基本上以无限的队列深度工作。
对于有多个客户端的 CephFS,“硬”I/O 模式确实很难:每次写入都会导致 RADOS 对象的部分修改以前被另一个客户端接触过,并且可能被另一个客户端同时接触,因此写入有以原子方式执行。没有 fsync() 调用除了最后也无济于事:fsync() 保证数据命中稳定存储,但是这个测试关心的是客户端之间的数据一致性,这是完全不同的事情,不能转在符合 POSIX 的文件系统中关闭。因此,即使测试以 GiB/s 显示结果,它主要受客户端和元数据服务器之间的通信延迟的影响。
对于阅读,简单测试和困难测试都使用与之前编写的相同的文件,以相同的方式访问它们,并验证文件中的数据是否与预期的签名匹配。
几乎所有的 IOPS 测试都是使用“mdtest”工具完成的。与 ior 不同的是,mdtest 会创建大量文件并强调元数据操作。
就像带宽测试一样,测试运行有两个“难度”级别:简单和困难。对于每个难度,每个进程在“创建”阶段创建大量测试文件(最多一百万),然后在测试的“统计”阶段检查所有文件,然后在“删除”阶段删除. 在每个阶段结束时,都会执行“同步”命令,并考虑其运行时间。
难考与易考的区别在于以下几个方面:
简单测试中每个文件为空,在“创建”阶段写入 3901 字节,稍后在硬测试中读回;
在简单的情况下,每个进程都有一个唯一的工作目录,而在困难的情况下使用一个共享目录。
Croit 带有一个内置的基于 fio 的基准,用于评估数据库应用程序中磁盘驱动器的原始性能。基准测试在后台运行此命令以获取并行作业数量的各种值(从 1 到 16):
fio --filename=/dev/XXX --direct=1 --fsync=1 --rw=write --bs=4k --numjobs=YYY --iodepth=1 --runtime=60 --time_based --group_reporting --name=4k-sync-write-YYY
没有理由不将此基准用作表征 NVMe 驱动器的“至少某种东西”,并用于客观地比较它们在各种 BIOS 设置下的性能。
直接的发现之一是不同的服务器具有不同的性能,尤其是在基准测试的 1-job 变体中,IOPS 介于 78K 和 91K 之间。16 个作业的数据更加一致,仅显示 548K(奇怪的是,在 1 个作业基准测试中最快的服务器上)和 566K IOPS 之间的差异。
最初认为这种变化的原因在于最初出现在“CPU 配置”菜单中的服务器上的不同 BIOS 设置。事实上,从高性能存储读取数据本身就是一项 CPU 密集型活动:在这种情况下,fio 消耗了 30% 的 CPU,而“ kworker/4:1H-kblockd
”内核线程则消耗了 12%。因此,让 CPU 达到尽可能高的时钟频率是合理的。
与直觉相反,将 BIOS 的“高级电源管理配置”区域中的“电源技术”参数设置为“禁用”是错误的做法。它将 CPU 频率锁定在最高的非涡轮状态,即 2.10 GHz,并使 3.70 GHz 频率不可用。然后,fio 存储基准测试只能产生 66K IOPS,这太糟糕了。
此 BIOS 区域中的另一个选项决定是 BIOS 还是操作系统控制能效偏差。如果控制权交给 BIOS,有一个设置告诉它做什么,而对于“Power Technology”参数的“Manual”设置,有很多选项可以微调 C-、P- 和T 状态。考虑到能源性能偏差控制以及对 C-、P-、 CPU 的 T 状态和 T 状态被提供给操作系统。在这两种情况下,NVMes 最初的基准测试都是 89K-91K IOPS。不幸的是,后来的一些调整(不知道究竟是什么)破坏了这一成就,最终结果再次导致单线程 84K 和 87K 写入 IOPS 之间的性能不一致。
好吧,至少,从那时起,所有服务器上的 BIOS 设置都变得一致了——见下表。这些设置背后的想法是尽可能多地控制 CPU 状态给操作系统,而不是硬件或 BIOS。croit 还发现超线程、LLC Prefetch 和 Extended APIC 并没有显着影响存储性能。因此,启用了所有 CPU 功能。
BIOS 设置 | 价值 |
超线程 [全部] | 使能够 |
启用核心 | 0(全部) |
监视器/Mwait | 汽车 |
执行禁用位 | 使能够 |
英特尔虚拟化技术 | 使能够 |
PPIN 控制 | 解锁/启用 |
硬件预取器 | 使能够 |
相邻缓存预取 | 使能够 |
DCU 流媒体预取器 | 使能够 |
DCU IP 预取器 | 使能够 |
LLC预取 | 使能够 |
扩展 APIC | 使能够 |
AES-NI | 使能够 |
电源技术 | 风俗 |
电源性能调整 | 操作系统控制 EPB |
SpeedStep(P 状态) | 使能够 |
EIST PSD 函数 | HW_ALL |
涡轮模式 | 使能够 |
硬件 P 状态 | 禁用 |
自治核心 C 状态 | 禁用 |
CPU C6 报告 | 汽车 |
增强的停止状态 (C1E) | 使能够 |
包 C 状态 | 汽车 |
软件控制的 T 状态 | 使能够 |
Mellanox 适配器无需任何调整即可达到 85+ Gbps 的吞吐量,但为此需要多个 TCP 流。将 net.core.rmem_max sysctl 设置为一个巨大的值将进一步将可实现的吞吐量提高到 94 Gbit/s,但不会提高基准分数,因此没有完成。
为了展示出色的吞吐量,我们在两台主机上运行了 iperf(版本 2.0.12),如下所示:
在“服务器”上: iperf -s -p 9999
在“客户端”上: iperf -c 10.10.49.33 -p 9999
,其中 10.10.49.33 是服务器 IP
对于单个 TCP 流(如上所示),iperf 指示 39.5 Gbit/s 的吞吐量。为了同时使用四个流,在客户端添加了“-P 4”参数,这使吞吐量达到了 87.8 Gbit/s。
吞吐量很好,但请记住,有些 IOR500 测试实际上是针对延迟的,它也需要优化。对于延迟测试,我们使用了两个客观基准:
在 RBD 设备上测量 4k 大小的写入 IOPS;
只是ping另一个主机。
RBD 基准测试命令(比 IOR500 更激进)是:
fio --ioengine=rbd --pool=rbd_benchmark --rbdname=rbd0 --direct=1 --fsync=1 --rw=write --bs=4k --numjobs=1 --iodepth=1 --runtime=60 --time_based --group_reporting --name=4k-sync-write-1
未经任何调整,它仅达到 441 IOPS。是的,与原始存储相比,减少了 200 多倍。
这里的限制因素之一是 CPU 时钟速度。Linux 内核中默认的“powersave”CPU 频率调节器将 CPU 时钟保持在较低水平,直到它发现工作负载过于繁重。在这种情况下,它可能仍然“太容易”(27%),并且不被视为提高频率的充分理由——这可以通过grep MHz /proc/cpuinfo | sort | tail -n 4
与 fio 同时运行类似 '' 来确认。
一旦客户端和 Ceph OSD 节点 ( cpupower frequency-set -g performance
) 上的 CPU 频率调节器都更改为“性能”,情况就会改善:2369 IOPS。
正如已经提到的,IO500 基准测试对网络延迟很敏感。如果不进行任何调整,延迟(由“ping”命令报告)为 0.178 毫秒,这意味着在整个请求-响应周期中,仅浪费了 0.356 毫秒。这里的 ping 时间加倍,因为有两跳对延迟很重要:从客户端到主 OSD,以及从主 OSD 到辅助 OSD。上一节的 fio 基准测试中每秒有 2369 个这样的周期,因此每个周期平均持续 0.422 毫秒。因此,减少延迟似乎非常重要。
事实证明,CPU 负载足够低,并且它的内核通过进入节能 C 状态来“打盹”。最深的这种状态是C6,根据“ cpupower idle-info
”,它需要0.133毫秒才能从它过渡出来。接下来的状态是 C1E、C1 和“CPUIDLE CORE POLL IDLE”(不节省任何电量),所有这些状态都需要不到 0.01 毫秒的时间才能退出。因此,下一个调整步骤是禁用 C6 状态。执行此操作的命令“ cpupower idle-set -D 11
”实际上意味着“禁用所有需要超过 0.011 毫秒才能退出的空闲状态”。结果:ping 时间下降到 0.054 毫秒,但 fio 基准测试仅产生 2079 IOPS - 比以前更差。这可能是因为不在 C6 中的内核降低了 CPU 可用的最大频率,并且,在这个“fio”基准测试中,达到可能的最高频率实际上更为重要。
尽管如此,正如我们稍后将看到的,禁用 C6 对整体 IO500 得分是有益的。
IO500 基准测试的源代码来自 https://github.com/VI4IO/io500-app。来自“io500-isc20”分支的代码(当时指向提交 46e0e53)无法编译,因为“extern”变量使用不当。幸运的是,该错误修复可从同一存储库的主分支获得。因此,所有基准测试都是通过提交 20efd24 完成的。我们知道新的 IO500 版本已于 2020 年 10 月 7 日创建,但为了保持一致性,继续提交 46e0e53。
基准测试的主脚本名为“ io500.sh
”。在文件的顶部,有一个“ io500_mpiargs
”变量,默认设置为“ -np 2
”,意思是“在本地运行两个进程”。为了测试分布式操作是否有效,将此变量更改为“ -np 4 -mca btl ^openib -mca btl_tcp_if_include 10.10.49.0/24 -oversubscribe -H 10.10.49.2,10.10.49.33 --allow-run-as-root
”,以便在两个客户端节点的每一个上启动两个进程。
“ -mca btl ^openib
”参数将 InfiniBand 从 OpenMPI 尝试的传输列表中排除。这是必要的,因为 Mellanox 网络适配器理论上支持 InfiniBand,但该集群中尚未配置 InfiniBand。基准测试不需要在工作人员之间发送大量数据,因此回退到 TCP 是可以接受的。
“ -mca btl_tcp_if_include 10.10.49.0/24
”参数指定在 OpenMPI 基准测试期间要使用的网络。如果没有这个参数,OpenMPI 有时会选择其中一台主机上的 docker0 接口作为主接口,并尝试从其他节点连接到 172.17.0.1,这将失败。
基准测试的所有阶段运行两次,一次使用 shell 脚本进行协调,一次使用 C 程序。这两个“驱动程序”以略微不同的格式打印结果,但在数量上并没有太大差异。出于这个原因,下面只提到基于 shell 的驱动程序报告的基准分数。
基准测试还需要一个配置文件。一个广泛评论的示例 config-full.ini 与基准源一起提供。但是,只需要几个选项:IO500 将写入数据的目录、删除缓存的可选脚本以及用于调试的缩短基准测试持续时间的方法。在找到最佳选项之前,每次都执行完整的基准测试是没有意义的,因此,石墙计时器设置为 30 秒。
[global]
datadir = /mnt/cephfs/default
drop-caches = TRUE
drop-caches-cmd = /usr/local/bin/drop_caches
[debug]
stonewall-time = 30
/usr/local/bin/drop_caches
脚本的内容 是:
#!/bin/sh
echo 3 > /proc/sys/vm/drop_caches
ssh 10.10.49.33 echo 3 ">" /proc/sys/vm/drop_caches
30 秒版本的基准测试运行良好,并在完全未调整(操作系统调整除外)集群上生成此报告,启用 C6 空闲状态(这是默认设置):
[RESULT] BW phase 1 ior_easy_write 6.021 GiB/s : time 35.83 seconds [RESULT] BW phase 2 ior_hard_write 0.068 GiB/s : time 43.69 seconds [RESULT] BW phase 3 ior_easy_read 5.144 GiB/s : time 46.86 seconds [RESULT] BW phase 4 ior_hard_read 0.219 GiB/s : time 13.52 seconds [RESULT] IOPS phase 1 mdtest_easy_write 10.334 kiops : time 32.09 seconds [RESULT] IOPS phase 2 mdtest_hard_write 5.509 kiops : time 45.68 seconds [RESULT] IOPS phase 3 find 123.770 kiops : time 4.71 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 31.086 kiops : time 10.67 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 30.733 kiops : time 8.19 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 4.868 kiops : time 68.13 seconds [RESULT] IOPS phase 7 mdtest_hard_read 5.734 kiops : time 43.88 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 3.443 kiops : time 75.07 seconds [SCORE] Bandwidth 0.822726 GiB/s : IOPS 12.6286 kiops : TOTAL 3.22333
禁用 C6 后,“ior_hard_write”测试得到显着提升,但大多数其他测试的结果更差。尽管如此,由于带宽和 IOPS,总体得分还是略有提高:
[RESULT] BW phase 1 ior_easy_write 5.608 GiB/s : time 35.97 seconds [RESULT] BW phase 2 ior_hard_write 0.101 GiB/s : time 36.17 seconds [RESULT] BW phase 3 ior_easy_read 4.384 GiB/s : time 47.43 seconds [RESULT] BW phase 4 ior_hard_read 0.223 GiB/s : time 16.30 seconds [RESULT] IOPS phase 1 mdtest_easy_write 10.614 kiops : time 31.73 seconds [RESULT] IOPS phase 2 mdtest_hard_write 4.884 kiops : time 43.06 seconds [RESULT] IOPS phase 3 find 157.530 kiops : time 3.47 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 26.136 kiops : time 12.88 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 30.081 kiops : time 6.99 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 5.122 kiops : time 65.74 seconds [RESULT] IOPS phase 7 mdtest_hard_read 7.689 kiops : time 27.35 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 3.382 kiops : time 64.18 seconds [SCORE] Bandwidth 0.86169 GiB/s : IOPS 13.0773 kiops : TOTAL 3.35687
这并不奇怪:ior_easy_write 步骤在“ior”进程消耗 100% CPU 时出现瓶颈,并且 C6 中零内核的可用时钟速度低于其他情况。为了避免这种 CPU 核心饱和现象,我们进行了单独的测试,每个主机有 4 个进程(而不是 2 个)。
启用 C6 的结果:
[RESULT] BW phase 1 ior_easy_write 7.058 GiB/s : time 38.88 seconds [RESULT] BW phase 2 ior_hard_write 0.074 GiB/s : time 39.40 seconds [RESULT] BW phase 3 ior_easy_read 7.933 GiB/s : time 34.78 seconds [RESULT] BW phase 4 ior_hard_read 0.172 GiB/s : time 16.97 seconds [RESULT] IOPS phase 1 mdtest_easy_write 11.416 kiops : time 34.38 seconds [RESULT] IOPS phase 2 mdtest_hard_write 5.492 kiops : time 43.10 seconds [RESULT] IOPS phase 3 find 169.540 kiops : time 3.71 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 41.339 kiops : time 9.50 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 47.345 kiops : time 5.00 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 8.997 kiops : time 43.63 seconds [RESULT] IOPS phase 7 mdtest_hard_read 9.854 kiops : time 24.02 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 3.213 kiops : time 75.66 seconds [SCORE] Bandwidth 0.919144 GiB/s : IOPS 16.6569 kiops : TOTAL 3.91281
禁用 C6 的结果:
[RESULT] BW phase 1 ior_easy_write 5.983 GiB/s : time 39.96 seconds [RESULT] BW phase 2 ior_hard_write 0.100 GiB/s : time 37.91 seconds [RESULT] BW phase 3 ior_easy_read 7.413 GiB/s : time 31.65 seconds [RESULT] BW phase 4 ior_hard_read 0.232 GiB/s : time 16.26 seconds [RESULT] IOPS phase 1 mdtest_easy_write 9.793 kiops : time 35.57 seconds [RESULT] IOPS phase 2 mdtest_hard_write 4.845 kiops : time 36.70 seconds [RESULT] IOPS phase 3 find 147.360 kiops : time 3.57 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 50.768 kiops : time 6.86 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 50.125 kiops : time 3.55 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 7.763 kiops : time 44.87 seconds [RESULT] IOPS phase 7 mdtest_hard_read 13.135 kiops : time 13.54 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 3.699 kiops : time 50.04 seconds [SCORE] Bandwidth 1.00608 GiB/s : IOPS 16.918 kiops : TOTAL 4.12563
结论保持不变:禁用 C6 的建议并不普遍。它有助于基准测试的一些“困难”地方,但会伤害其他地方。尽管如此,它在两种情况下都略微提高了整体分数,因此在其余基准测试中禁用了 C6。
简短版的测试运行顺利。但是,在使用默认 300 秒石墙计时器的完整基准测试期间(特别是在“mdtest_hard_write”阶段),观察到一些 MDS 健康警告:
MDSs 落后于修剪
MDS 报告缓存过大
客户端无法响应缓存压力
最终得分也较低,特别是由于基于 mdtest 的“stat”测试:
[RESULT] BW phase 1 ior_easy_write 5.442 GiB/s : time 314.02 seconds [RESULT] BW phase 2 ior_hard_write 0.099 GiB/s : time 363.64 seconds [RESULT] BW phase 3 ior_easy_read 7.838 GiB/s : time 215.95 seconds [RESULT] BW phase 4 ior_hard_read 0.231 GiB/s : time 155.15 seconds [RESULT] IOPS phase 1 mdtest_easy_write 11.423 kiops : time 431.68 seconds [RESULT] IOPS phase 2 mdtest_hard_write 5.518 kiops : time 328.02 seconds [RESULT] IOPS phase 3 find 120.880 kiops : time 55.76 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 0.866 kiops : time 5694.08 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 2.072 kiops : time 873.55 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 1.972 kiops : time 2500.54 seconds [RESULT] IOPS phase 7 mdtest_hard_read 1.925 kiops : time 940.46 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 3.304 kiops : time 549.71 seconds [SCORE] Bandwidth 0.99279 GiB/s : IOPS 4.51093 kiops : TOTAL 2.11622
显然,MDS 被基准测试创建的元数据负载压得喘不过气来。因此,决定将“mds 缓存内存限制” Ceph 参数从默认值 1 GB 增加到 12884901888 (12 GB)。选择的确切值是健康警告中报告的峰值缓存大小的 2 倍。这几乎恢复了在基准测试的简短版本中看到的分数:
[RESULT] BW phase 1 ior_easy_write 5.274 GiB/s : time 322.44 seconds [RESULT] BW phase 2 ior_hard_write 0.105 GiB/s : time 348.94 seconds [RESULT] BW phase 3 ior_easy_read 7.738 GiB/s : time 217.92 seconds [RESULT] BW phase 4 ior_hard_read 0.239 GiB/s : time 153.87 seconds [RESULT] IOPS phase 1 mdtest_easy_write 10.692 kiops : time 429.36 seconds [RESULT] IOPS phase 2 mdtest_hard_write 5.318 kiops : time 324.34 seconds [RESULT] IOPS phase 3 find 211.550 kiops : time 29.85 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 44.120 kiops : time 104.05 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 29.881 kiops : time 57.72 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 6.993 kiops : time 656.42 seconds [RESULT] IOPS phase 7 mdtest_hard_read 9.773 kiops : time 176.46 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 2.949 kiops : time 586.78 seconds [SCORE] Bandwidth 1.0071 GiB/s : IOPS 15.4197 kiops : TOTAL 3.94071
将每台主机的 worker 数量增加到 4 个以上并没有提高 IO500 分数,也没有增加 OSD 的 CPU 使用率。在这种情况下,“ior”阶段可能的瓶颈是单个客户端“kworker/u194:0+flush-ceph-1”线程,它消耗了 70-80% 的 CPU。这个线程是单线程的,因为一台主机上的所有工作进程只使用一个 cephfs 挂载。
很明显,解决方案是多次挂载 cephfs,这样它们就不会共享一个“kworker/u194:0+flush-ceph-1”线程。此挂载选项称为“noshare”。以下是“mount.ceph”手册页中的描述:
创建一个新的客户端实例,而不是共享挂载同一集群的现有客户端实例。
但是,IO500 基准测试并非旨在通过多个挂载点访问存储。为了规避这个限制,在每个客户端主机上创建了多个 LXC 容器,每个容器都有一个单独的 cephfs 挂载。对于网络,使用了“macvlan”后端,以便将每个容器直接暴露给 100Gbps 网络,而不会因路由而产生额外开销。在每个主机本身上,都添加了一个单独的 macvlan 接口,以便容器可以与主机通信。以下是相关部分 /etc/network/interfaces
:
iface enp216s0f0np0 inet manual up /sbin/ip link add link enp216s0f0np0 name enp216s0f0mv0 type macvlan mode bridge allow-hotplug enp216s0f0mv0 iface enp216s0f0mv0 inet static address 10.10.49.2/24
无法从容器中刷新 Linux 缓存,因此,容器中的“ /usr/local/bin/drop_caches
”脚本必须修改如下:
#!/bin/sh ssh 10.10.49.2 echo 3 ">" /proc/sys/vm/drop_caches ssh 10.10.49.33 echo 3 ">" /proc/sys/vm/drop_caches
也就是说,它将通过 ssh 连接到两个客户端主机,并以通常的方式刷新缓存。
每个主机四个容器,每个容器三个或四个工作进程获得了最佳结果。规定这一点的 mpirun 参数是:“ -np 32 -oversubscribe -H 10.10.49.3,10.10.49.4,... --allow-run-as-root
”。事实上,使用 30 秒的石墙计时器,基准测试的某些阶段,例如“mdtest_hard_stat”,变得太短(不到 4 秒),结果变得可靠和可重复。因此,从此时起,基准测试使用 300 秒的石墙计时器运行。
以下是每个容器三个进程的基准测试结果:
[RESULT] BW phase 1 ior_easy_write 11.307 GiB/s : time 372.62 seconds [RESULT] BW phase 2 ior_hard_write 0.383 GiB/s : time 352.78 seconds [RESULT] BW phase 3 ior_easy_read 15.144 GiB/s : time 277.94 seconds [RESULT] BW phase 4 ior_hard_read 0.931 GiB/s : time 145.10 seconds [RESULT] IOPS phase 1 mdtest_easy_write 14.032 kiops : time 472.96 seconds [RESULT] IOPS phase 2 mdtest_hard_write 9.891 kiops : time 313.09 seconds [RESULT] IOPS phase 3 find 231.190 kiops : time 42.10 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 55.821 kiops : time 118.89 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 79.348 kiops : time 39.03 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 9.597 kiops : time 691.54 seconds [RESULT] IOPS phase 7 mdtest_hard_read 16.702 kiops : time 185.42 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 8.507 kiops : time 366.75 seconds [SCORE] Bandwidth 2.79532 GiB/s : IOPS 25.7583 kiops : TOTAL 8.48544
每个容器有四个进程,一些基准测试结果(特别是“mdtest_hard_read”)看起来更好,但其他看起来更糟,集群肯定感觉过载(报告的中值延迟接近 0.5 秒)。因此,这里每个容器使用三个或四个工作进程是否更好是有争议的。以下是基准测试结果:
[RESULT] BW phase 1 ior_easy_write 11.459 GiB/s : time 350.88 seconds [RESULT] BW phase 2 ior_hard_write 0.373 GiB/s : time 354.69 seconds [RESULT] BW phase 3 ior_easy_read 16.011 GiB/s : time 250.28 seconds [RESULT] BW phase 4 ior_hard_read 0.930 GiB/s : time 142.02 seconds [RESULT] IOPS phase 1 mdtest_easy_write 15.894 kiops : time 441.59 seconds [RESULT] IOPS phase 2 mdtest_hard_write 10.690 kiops : time 313.34 seconds [RESULT] IOPS phase 3 find 174.440 kiops : time 59.44 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 55.944 kiops : time 125.46 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 66.896 kiops : time 50.07 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 9.371 kiops : time 748.99 seconds [RESULT] IOPS phase 7 mdtest_hard_read 19.120 kiops : time 175.18 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 9.948 kiops : time 340.54 seconds [SCORE] Bandwidth 2.82402 GiB/s : IOPS 25.8226 kiops : TOTAL 8.53953
这是一个相当严重的负载:在 Ceph 集群中,每个 OSD cpu 消耗在“ior_easy_write”阶段达到约 400% 的峰值。这也是第一次观察到总客户端吞吐量超过单个 100Gbps 链路的能力。
前面几节中执行的 MDS 调优显然已经完成了——在“mdtest_easy_delete”和“mdtest_hard_delete”两个阶段,每个活动 ceph-mds 进程的 CPU 使用率都接近 100%。换句话说,只有四个活动的 MDS,这与集群在这些元数据密集型基准测试中的运行速度差不多。
但是谁说有五台物理服务器,一台受限于四台活动 MDS 和一台备用?croit 用户界面。Ceph 官方文档 提到每个节点多个 MDS 作为 MDS 瓶颈的可能解决方案:
即使单个 MDS 守护程序无法充分利用硬件,稍后可能需要在同一节点上启动更多活动的 MDS 守护程序以充分利用可用的内核和内存。此外,集群上的工作负载可能会清楚地表明,在同一节点上使用多个活动 MDS 会提高性能,而不是过度配置单个 MDS。
事实上,我们发现即使每个主机有两个 MDS 也不足以避免瓶颈。因此,我们总共部署了 20 个 MDS——每台主机 4 个,并使其中 16 个处于活动状态。因此,这是我们使用的手动程序。
在每台主机上,必须(暂时)将管理员密钥环保存为 /etc/ceph/ceph.client.admin.keyring
. 之后,执行以下命令,替换正确的主机名,而不是 croit-host-25
为新的 MDS 组成唯一的名称。
# sudo -u ceph -s /bin/bash $ mkdir /var/lib/ceph/mds/ceph-croit-host-25a $ ceph-authtool --create-keyring /var/lib/ceph/mds/ceph-croit-host-25a/keyring --gen-key -n mds.croit-host-25a $ ceph auth add mds.croit-host-25a osd "allow rwx" mds "allow" mon "allow profile mds" -i /var/lib/ceph/mds/ceph-croit-host-25a/keyring $ cat /var/lib/ceph/mds/ceph-croit-host-25a/keyring
结果,每个主机拥有三个新的有效密钥环,每个未来的 MDS 一个。在 croit 容器中,必须将它们插入到数据库中——这是 UI 不允许的。
$ mysql croit MariaDB [croit]> insert into service values(NULL, 5, 'mds', NULL, 'croit-host-25a', '[mds.croit-host-25a]\nkey = AQA9jn1f7oyKDRAACIJ0Kj8e8D1C4z4p8hU2WA==\n', 'enabled', NOW(), NULL); [and the remaining keys]
然后 croit 在每个集群节点上启动额外的 MDS 守护程序,这些额外的守护程序甚至在滚动重启后仍然存在。
最后,要使它们处于活动状态,需要以下命令:
ceph fs set cephfs max_mds 16
正如预期的那样,基准测试结果有所改善(每个容器有四个工作进程):
[RESULT] BW phase 1 ior_easy_write 13.829 GiB/s : time 325.93 seconds [RESULT] BW phase 2 ior_hard_write 0.373 GiB/s : time 365.60 seconds [RESULT] BW phase 3 ior_easy_read 16.204 GiB/s : time 278.80 seconds [RESULT] BW phase 4 ior_hard_read 0.920 GiB/s : time 148.24 seconds [RESULT] IOPS phase 1 mdtest_easy_write 25.154 kiops : time 594.93 seconds [RESULT] IOPS phase 2 mdtest_hard_write 13.227 kiops : time 316.73 seconds [RESULT] IOPS phase 3 find 391.840 kiops : time 48.88 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 153.305 kiops : time 97.61 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 93.870 kiops : time 44.63 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 20.886 kiops : time 716.49 seconds [RESULT] IOPS phase 7 mdtest_hard_read 28.205 kiops : time 148.53 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 10.496 kiops : time 401.73 seconds [SCORE] Bandwidth 2.96175 GiB/s : IOPS 42.959 kiops : TOTAL 11.2798
看起来每个主机四个 MDS 确实是集群可以有用的最大值。我们不再看到它们长时间消耗 100% CPU 的时期。现在的典型数字是 120% + 80% + 60% + 20%。
理论上,可以使用 OSD 进行相同类型的额外配置。事实上,在过去,一个常见的建议是为每个 SSD 配置几个 (2-4) 个 OSD。现代 Ceph 提供了不同的解决方案:由“osd op num shards”和“osd op num threads per shard”参数控制的内置 OSD 分片。我们调查了这两个选项,但发现它们都不能提高整体基准分数。唯一持续改进的指标是“mdtest_hard_stat”,但这被分数的其他部分变得更差所抵消。
Bluestore OSD 使用自己的缓存而不是 Linux 页面缓存来存储可能再次需要的副本数据。通常,从其默认值(croit 中 3 GB)增加“osd memory target”可调参数应该可以提高性能,因为这样 OSD 将从缓存中提供更多服务,而从磁盘中提供更少服务。但是这个特定的基准测试旨在使缓存尽可能无效:它只有在将数据全部写入后才读取数据。因此,并且我们已经通过实验证实,增加 OSD 内存目标对最终得分没有影响。
到目前为止,所有基准测试都是使用默认 MTU (1500) 和套接字缓冲区大小进行的。但是,通常建议在高速网络上将 MTU 设置为 9000,而我们的 100Gbps 网络当然可以满足要求。此外,建议增加套接字缓冲区大小的限制和默认值。
我们首先将 OSD 节点和客户端上的 MTU 增加到 9000。增加 MTU 后,“ior_easy_write”阶段的性能确实提升到了 15.163 GiB/s。但是,我们无法完成基准测试,因为“MDS 在修剪时落后”和“MDS 操作缓慢”健康警告,以及由此产生的客户端黑名单。然后一个 MDS 进入只读模式,这通常发生在文件系统以某种方式损坏时。
我们继续使用 iperf 重新测试网络吞吐量。这比以前更糟。使用 MTU 1500 和默认套接字缓冲区大小,我们能够使用四个并发连接达到 87 Gbit/s。使用 MTU 9000,我们只有 77 Gbit/s。显然,网卡在发送时可以有效地执行 TCP 分段卸载,而在接收时则相反,只有 MTU = 1500。
MTU 调整被撤消,不幸的是,文件系统不得不被销毁并重新创建。
我们尝试让 Linux 内核在 OSD 和客户端上使用以下 sysctls 将 TCP 缓冲区自动调整为更大的值:
net.core.rmem_max=33554432 net.core.wmem_max=33554432 net.ipv4.tcp_rmem=4096 65536 33554432 net.ipv4.tcp_wmem=4096 131072 33554432
结果再次降低了分数:
[RESULT] BW phase 1 ior_easy_write 12.905 GiB/s : time 351.74 seconds [RESULT] BW phase 2 ior_hard_write 0.382 GiB/s : time 354.09 seconds [RESULT] BW phase 3 ior_easy_read 16.459 GiB/s : time 275.82 seconds [RESULT] BW phase 4 ior_hard_read 0.926 GiB/s : time 145.97 seconds [RESULT] IOPS phase 1 mdtest_easy_write 24.030 kiops : time 637.19 seconds [RESULT] IOPS phase 2 mdtest_hard_write 12.289 kiops : time 331.97 seconds [RESULT] IOPS phase 3 find 252.270 kiops : time 76.87 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 95.420 kiops : time 160.47 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 97.223 kiops : time 41.96 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 16.660 kiops : time 919.06 seconds [RESULT] IOPS phase 7 mdtest_hard_read 15.179 kiops : time 268.76 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 8.265 kiops : time 497.80 seconds [SCORE] Bandwidth 2.9435 GiB/s : IOPS 33.1105 kiops : TOTAL 9.87222
就像任何其他糟糕的调整尝试一样,这些设置都被撤消了。
为了防止我们在 MTU = 9000 时看到的“MDSs behind on trimming”健康警告,我们尝试将“mds log max segments”选项设置为 1280(这大约是警告中 num_segments 峰值的 2 倍)。这严重降低了 mdtest 的性能,因此也被撤消了。这是 MTU = 1500 的基准报告:
[RESULT] BW phase 1 ior_easy_write 12.733 GiB/s : time 335.69 seconds [RESULT] BW phase 2 ior_hard_write 0.374 GiB/s : time 348.14 seconds [RESULT] BW phase 3 ior_easy_read 17.026 GiB/s : time 256.40 seconds [RESULT] BW phase 4 ior_hard_read 0.932 GiB/s : time 139.58 seconds [RESULT] IOPS phase 1 mdtest_easy_write 26.622 kiops : time 575.94 seconds [RESULT] IOPS phase 2 mdtest_hard_write 12.984 kiops : time 328.36 seconds [RESULT] IOPS phase 3 find 341.760 kiops : time 57.34 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 107.865 kiops : time 142.15 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 103.463 kiops : time 41.21 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 14.181 kiops : time 1081.19 seconds [RESULT] IOPS phase 7 mdtest_hard_read 15.855 kiops : time 268.90 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 8.702 kiops : time 493.00 seconds [SCORE] Bandwidth 2.94821 GiB/s : IOPS 35.5994 kiops : TOTAL 10.2447
在基准测试的 IOR 阶段,可以看到“kswapd[01]”内核线程占用了客户端 100% 的 CPU。“kswapd”线程(每个 NUMA 节点一个)使 Linux 内存子系统对空闲页面的数量感到满意。特别是,他们尝试回收页面缓存。因此,看起来这些基准测试阶段产生了太多脏页或缓存页。基准测试提供了一个选项(“ posix.odirect = True
”在 [global]
配置文件的部分或特定阶段的部分中)通过 O_DIRECT
标志绕过页面缓存。然而,它实际上使每个 IOR 阶段的得分更差,即与预期效果完全相反。
为了使更多的 CPU 时间(实际上是更多的 CPU)可用于页面缓存回收任务,使用“ numa=fake=8
”内核命令行参数在两个客户端上创建了一组假 NUMA 节点。结果:这对 IOR 阶段没有帮助(所以 kswapd 毕竟不是瓶颈),而是伤害了“查找”和大多数基于 mdtest 的阶段。
[RESULT] BW phase 1 ior_easy_write 13.674 GiB/s : time 342.55 seconds [RESULT] BW phase 2 ior_hard_write 0.381 GiB/s : time 355.32 seconds [RESULT] BW phase 3 ior_easy_read 16.784 GiB/s : time 278.14 seconds [RESULT] BW phase 4 ior_hard_read 0.925 GiB/s : time 146.32 seconds [RESULT] IOPS phase 1 mdtest_easy_write 23.718 kiops : time 578.62 seconds [RESULT] IOPS phase 2 mdtest_hard_write 11.818 kiops : time 326.18 seconds [RESULT] IOPS phase 3 find 261.800 kiops : time 67.14 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 101.016 kiops : time 135.85 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 69.404 kiops : time 55.54 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 18.087 kiops : time 758.75 seconds [RESULT] IOPS phase 7 mdtest_hard_read 26.474 kiops : time 145.60 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 9.933 kiops : time 390.60 seconds [SCORE] Bandwidth 2.99932 GiB/s : IOPS 35.3655 kiops : TOTAL 10.2991
因此,这也必须撤消。
无所事事不应该受到伤害。它也不应该有帮助,因此它是测试基准结果可重复性的好方法。因此,在撤消所有糟糕的优化后,我们有望重新获得我们之前看到的高分。让我们检查:
[RESULT] BW phase 1 ior_easy_write 13.359 GiB/s : time 455.21 seconds [RESULT] BW phase 2 ior_hard_write 0.376 GiB/s : time 338.87 seconds [RESULT] BW phase 3 ior_easy_read 16.634 GiB/s : time 366.70 seconds [RESULT] BW phase 4 ior_hard_read 0.934 GiB/s : time 136.30 seconds [RESULT] IOPS phase 1 mdtest_easy_write 24.508 kiops : time 606.63 seconds [RESULT] IOPS phase 2 mdtest_hard_write 12.352 kiops : time 329.28 seconds [RESULT] IOPS phase 3 find 288.930 kiops : time 65.53 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 109.363 kiops : time 135.95 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 98.175 kiops : time 41.43 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 18.731 kiops : time 793.72 seconds [RESULT] IOPS phase 7 mdtest_hard_read 26.504 kiops : time 153.46 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 10.293 kiops : time 397.73 seconds [SCORE] Bandwidth 2.9722 GiB/s : IOPS 38.4718 kiops : TOTAL 10.6933
不完全在那里(主要是因为“发现”),但至少仍然比目前讨论的所有错误的优化尝试要好。因此,结论仍然有效。
请记住,我们在每个节点上设置了两个 NVME 驱动器,因此它们不参与基准测试。现在是把它们带回来的时候了,因此,也许可以证明底层存储至少是瓶颈的一部分。
[RESULT] BW phase 1 ior_easy_write 12.982 GiB/s : time 391.63 seconds [RESULT] BW phase 2 ior_hard_write 0.383 GiB/s : time 349.43 seconds [RESULT] BW phase 3 ior_easy_read 16.991 GiB/s : time 304.82 seconds [RESULT] BW phase 4 ior_hard_read 0.923 GiB/s : time 145.14 seconds [RESULT] IOPS phase 1 mdtest_easy_write 23.997 kiops : time 600.49 seconds [RESULT] IOPS phase 2 mdtest_hard_write 11.300 kiops : time 335.35 seconds [RESULT] IOPS phase 3 find 345.570 kiops : time 52.66 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 113.218 kiops : time 127.28 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 99.407 kiops : time 38.12 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 19.261 kiops : time 748.14 seconds [RESULT] IOPS phase 7 mdtest_hard_read 28.119 kiops : time 134.76 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 10.485 kiops : time 364.02 seconds [SCORE] Bandwidth 2.97168 GiB/s : IOPS 39.5523 kiops : TOTAL 10.8414
嗯,改进是微不足道的。另一方面,每个节点只有四个 OSD(即使我们策略性地选择它们,使其 NVMe 驱动器的 NUMA 节点与网卡的 NUMA 节点匹配),分数略有降低,因为 NVME 驱动器在 IOR 期间过载阶段:
[RESULT] BW phase 1 ior_easy_write 10.775 GiB/s : time 344.10 seconds [RESULT] BW phase 2 ior_hard_write 0.374 GiB/s : time 359.87 seconds [RESULT] BW phase 3 ior_easy_read 16.431 GiB/s : time 224.47 seconds [RESULT] BW phase 4 ior_hard_read 0.925 GiB/s : time 145.59 seconds [RESULT] IOPS phase 1 mdtest_easy_write 25.422 kiops : time 641.73 seconds [RESULT] IOPS phase 2 mdtest_hard_write 12.040 kiops : time 324.63 seconds [RESULT] IOPS phase 3 find 374.070 kiops : time 54.06 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 101.753 kiops : time 160.33 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 78.571 kiops : time 49.74 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 19.180 kiops : time 850.58 seconds [RESULT] IOPS phase 7 mdtest_hard_read 25.747 kiops : time 151.80 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 9.840 kiops : time 399.77 seconds [SCORE] Bandwidth 2.79783 GiB/s : IOPS 38.1085 kiops : TOTAL 10.3257
因此,虽然存储量确实会影响性能,但影响很小。这是真正的瓶颈在别处的理论的论据。
正如我们已经提到的,对于这种规模的集群,创建 cephfs_data 池的 PG (512) 少于通常推荐的 (1024)。只是为了测试,我们将池的大小调整为 1024 个 PG。结果是分数略有下降:
[RESULT] BW phase 1 ior_easy_write 13.373 GiB/s : time 349.24 seconds [RESULT] BW phase 2 ior_hard_write 0.376 GiB/s : time 361.25 seconds [RESULT] BW phase 3 ior_easy_read 16.557 GiB/s : time 282.76 seconds [RESULT] BW phase 4 ior_hard_read 0.912 GiB/s : time 148.76 seconds [RESULT] IOPS phase 1 mdtest_easy_write 20.689 kiops : time 793.92 seconds [RESULT] IOPS phase 2 mdtest_hard_write 11.058 kiops : time 344.35 seconds [RESULT] IOPS phase 3 find 333.310 kiops : time 60.70 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 143.516 kiops : time 114.45 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 104.899 kiops : time 36.30 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 19.006 kiops : time 864.21 seconds [RESULT] IOPS phase 7 mdtest_hard_read 23.765 kiops : time 160.23 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 9.188 kiops : time 417.02 seconds [SCORE] Bandwidth 2.95176 GiB/s : IOPS 38.4369 kiops : TOTAL 10.6516
每个节点有 8 个 OSD。
作为我们测试的最后一部分,我们安装了一个夜间版本的 croit 容器,并使用它来将集群升级到 Ceph Octopus(版本 15.2.5)。这确实会导致一些差异:
[RESULT] BW phase 1 ior_easy_write 13.656 GiB/s : time 347.14 seconds [RESULT] BW phase 2 ior_hard_write 0.332 GiB/s : time 356.28 seconds [RESULT] BW phase 3 ior_easy_read 16.740 GiB/s : time 282.90 seconds [RESULT] BW phase 4 ior_hard_read 0.790 GiB/s : time 149.64 seconds [RESULT] IOPS phase 1 mdtest_easy_write 26.457 kiops : time 436.90 seconds [RESULT] IOPS phase 2 mdtest_hard_write 12.974 kiops : time 335.61 seconds [RESULT] IOPS phase 3 find 413.790 kiops : time 38.46 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 117.764 kiops : time 98.16 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 90.990 kiops : time 47.85 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 20.957 kiops : time 551.56 seconds [RESULT] IOPS phase 7 mdtest_hard_read 25.622 kiops : time 169.94 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 9.646 kiops : time 453.91 seconds [SCORE] Bandwidth 2.7817 GiB/s : IOPS 40.9341 kiops : TOTAL 10.6708
“hard”测试的带宽更少,“find”和“mdtest_easy_write”的IOPS更高,但最终得分相同。
我们还在 Ceph Octopus 上重新测试了 MTU 9000。这一次,集群在基准测试中幸存下来,并确认了对“ior_easy_write”阶段的积极影响,但总体得分有所下降:
[RESULT] BW phase 1 ior_easy_write 15.608 GiB/s : time 343.82 seconds [RESULT] BW phase 2 ior_hard_write 0.333 GiB/s : time 356.22 seconds [RESULT] BW phase 3 ior_easy_read 14.657 GiB/s : time 368.92 seconds [RESULT] BW phase 4 ior_hard_read 0.783 GiB/s : time 151.37 seconds [RESULT] IOPS phase 1 mdtest_easy_write 25.044 kiops : time 557.53 seconds [RESULT] IOPS phase 2 mdtest_hard_write 11.682 kiops : time 326.95 seconds [RESULT] IOPS phase 3 find 394.750 kiops : time 45.04 seconds [RESULT] IOPS phase 4 mdtest_easy_stat 121.566 kiops : time 114.85 seconds [RESULT] IOPS phase 5 mdtest_hard_stat 91.986 kiops : time 41.52 seconds [RESULT] IOPS phase 6 mdtest_easy_delete 19.932 kiops : time 700.49 seconds [RESULT] IOPS phase 7 mdtest_hard_read 21.683 kiops : time 176.15 seconds [RESULT] IOPS phase 8 mdtest_hard_delete 8.189 kiops : time 471.37 seconds [SCORE] Bandwidth 2.77798 GiB/s : IOPS 38.2382 kiops : TOTAL 10.3065
因此,我们可以得出结论,11.27 是我们在该集群的 IO500 基准测试中可以获得的最高分,而 10.84 是我们可以重复获得的最高分。
如果没有解释为什么测试不能更快,基准报告是不完整的。也就是说,没有确定无法消除的瓶颈。
“ior_easy_write”阶段是独一无二的,因为它在多个因素上成为瓶颈或几乎成为瓶颈:使用较少的 OSD,这将是磁盘性能,而使用 MTU 1500,这是网络吞吐量(在 OSD 上为 80 Gbit/s)。此外,在客户端上,kswapd 的 CPU 使用可能是一个问题(但我们无法确认这实际上是一个问题)。
禁用 C6 会对几个阶段(“ior_hard_write”、“ior_hard_read”、“mdtest_hard_write”)产生积极影响,也就是说,它们对网络延迟很敏感。甚至更多(“mdtest_easy_write”、“mdtest_easy_stat”、“mdtest_hard_stat”、“mdtest_easy_delete”、“mdtest_hard_read”)导致 MDS 的 CPU 使用率飙升至 100%,因为 MDS 大多是单线程的,这表明瓶颈。对于两个阶段(“find”和“mdtest_hard_delete”),我们无法确定确切的瓶颈,但它们会受到添加额外 MDS 的积极影响,所以可能就是这样。
Ceph 有许多可调参数。但是,这里只需要其中一个(mds 缓存内存限制)。剩下的工作就是调整 Linux 操作系统、规划集群和创建足够的客户端。