Ceph Reef - 每个 NVMe 使用 1 个或 2 个 OSD?

大家好,Ceph 社区!又到了发布一篇博客文章的时候了!多年来,我们收到最常见的问题之一是用户是否应该在闪存驱动器上部署多个 OSD。这个问题尤其复杂,因为我们的建议多年来发生了变化。在 Ceph Nautilus 时代,我们经常建议每个闪存驱动器部署 2 个甚至 4 个 OSD。当时,在每个闪存设备上部署多个 OSD 具有明显且重要的性能优势,尤其是在使用 NVMe 驱动器时。
在 Octopus 和 Pacific 开发周期中,情况开始发生变化。我们引入了多个性能改进,这些改进在 OSD 和 BlueStore 代码中(例如 此处 和 此处)极大地提高了每个 OSD 的性能。在 Pacific 即将完成时,我们运行了各种测试,以确定是否应该更改我们的建议。
正如预期的那样,Octopus 和 Pacific 比 Nautilus 快得多,但也不再显示在每个 NVMe 上使用 2 个 OSD 与 1 个 OSD 相比,性能始终如一地提高。一些测试仍然显示了一些收益,而另一些测试则显示了轻微的损失。然而,这些测试的范围相当有限。CPU 资源的可利用性会改变结果吗?在性能或资源消耗方面还有其他优势或劣势吗?最后,我们自 Pacific 以来一直在改进 OSD 和 bluestore 代码。我们今天看到类似的行为吗?请继续阅读以了解!
致谢
首先,感谢 Clyso 为这项工作提供资金,以造福 Ceph 社区。同时感谢 IBM / Red Hat、Intel 和 Samsung 向 Ceph 上游社区提供用于本次测试的硬件。同时感谢所有为 Ceph 的伟大而不知疲倦地工作过的 Ceph 开发人员!最后,特别感谢 Anthony D'Atri 担任本文档的编辑并批准了数分钟内的修复。感谢您的帮助 Anthony,以及您为 Ceph Docs 所做的一切!
集群设置
| 节点 | 10 x Dell PowerEdge R6515 |
|---|---|
| CPU | 1 x AMD EPYC 7742 64C/128T |
| 内存 | 128GiB DDR4 |
| 网络 | 1 x 100GbE Mellanox ConnectX-6 |
| NVMe | 6 块 4TB Samsung PM983 |
| 操作系统版本 | CentOS Stream release 8 |
| Ceph 版本 | Reef v18.2.0 (从源代码构建) |
5 个节点配置为托管 OSD,5 个节点配置为客户端节点。所有节点都位于同一 Juniper QFX5200 交换机上,并通过单个 100GbE QSFP28 链路连接。Ceph 已部署,并且使用 CBT 启动了 FIO 测试。在 Intel 系统上,一个重要的操作系统级别优化是将 TuneD 配置文件设置为“latency-performance”或“network-latency”。这主要通过避免与 CPU C/P 状态转换相关的延迟峰值来帮助。基于 AMD Rome 的系统似乎不太敏感,并且我尚未确认 TuneD 实际上限制了 AMD 处理器的 C/P 状态转换。尽管如此,TuneD 配置文件仍然设置为“network-latency”用于这些测试。
测试设置
CBT 配置为使用一些修改后的设置部署 Ceph。通常,在测试 Ceph 时,人们会考虑每个 OSD 分配的核心数和内存量。但是,在此测试中,最好考虑每个 NVMe 驱动器可用的 CPU 和内存量。这些系统中的每一个都可以舒适地支持每个 NVMe 驱动器 16GB 的内存,并且可以扩展到每个 NVMe 20 个 CPU 线程。为了保持正确的内存比率,在 1 OSD/NVMe 的情况下,osd_memory_target 设置为 16GB,在 2 OSD/NVMe 的情况下设置为 8GB。Numactl 用于控制每个 OSD 的 CPU 线程数。OSD 被分配到“处理器”的两个池中,以尝试同时扩展物理和 HT 核心。为此,使用以下 bash 一行命令生成物理核心到处理器的映射:
paste <(cat /proc/cpuinfo | grep "core id") <(cat /proc/cpuinfo | grep "processor") | sed 's/[[:blank:]]/ /g'
这表明处理器 0-63 对应于物理核心,处理器 64-127 对应于 HT 核心。接下来,调用 numactl 以使用相同数量的物理和 HT 处理器(我们将在本文中通常将其称为 CPU 线程)。例如,要将 OSD 分配到 12 个物理和 12 个 HT 核心的池(总共 24 个 CPU 线程,或每个 NVMe 4 个线程),OSD 的调用方式如下:
...numactl --physcpubind=0-12,64-76 /usr/local/bin/ceph-osd
测试是在每个 NVMe 驱动器 2 到 20 个 CPU 线程之间进行的。FIO 配置为首先使用大写填充 RBD 卷,然后进行 60 秒的 4MB 和 4KB IO 测试。某些后台进程,例如 scrub、deep scrub、PG 自动缩放和 PG 平衡被禁用。使用了具有静态 16384 PGs(高于通常建议的值)和 3 倍复制的 RBD 池。
4MB 吞吐量
当我开始这项测试时,我没有期望看到多个 OSD 每 NVMe 设备在大型 IO 工作负载方面有显著的性能差异。对于读取,差异相对较小,但 2 OSD 配置显示出相当一致的较小优势。但是,对于写入,我惊讶地观察到,在 12 个 CPU 线程每 NVMe 时,吞吐量下降幅度达到峰值,与单个 OSD 配置相比。
这些是短时间运行的测试,但我们在每个 CPU 计数样本点重新创建了集群,并且我们看到一个明确的趋势,经过多次采样。这种影响可能是真实的,并且似乎与我们在 Octopus 和 Pacific 中观察到的行为相符,当时 4MB 写入吞吐量实际上在 2 OSD/NVMe 配置中较低。不幸的是,我还没有对此行为的解释。
4KB 随机 IOPS
使用 Nautilus,我们在 4KB 随机读和随机写测试中都看到了 2 OSD/NVMe 的显著优势。在相同的硬件、相同的操作系统、相同的内核版本以及运行完全相同的测试上,我们在 Octopus 和 Pacific 中看到了不同的行为。我们不再拥有相同的硬件或操作系统来进行这些 Reef 测试,但我们看到的行为更接近于我们在之前的测试平台上看到的 Pacific 行为。除非您有 16 个 CPU 线程每 NVMe 驱动器或更多,否则部署每个 NVMe 驱动器上的 2 个 OSD 没有特别的 IOPS 优势。事实上,对于具有 2-4 个 CPU 线程每 NVMe 的部署,IOPS 会略有下降。从这些测试中可以得出几个立即可用的结论:
- 使用默认调整,OSD 的扩展不会超过大约 14-16 个 CPU 线程。
- 随机读取受益于多个 OSD 超过高 CPU 线程数时的随机写入。
- 在低 CPU 线程数下运行多个 OSD 每 NVMe 会增加一些额外的开销。
但是 IOPS 并不是唯一的考虑因素。那延迟呢?资源消耗呢?
4KB 随机延迟
在这些测试中,我们有 50 个 fio 客户端进程,每个进程的 io_depth 为 128。Ceph 可以实现显著更低的平均延迟,但在这种情况下,我们正在使 OSD 饱和,以至于完全受 CPU 限制。在这种情况下,延迟直接与 IOPS 成比例。
平均延迟降低的模式与我们在 IOPS 中看到的模式相似。在低 CPU 线程数下,2 个 OSD 每 NVMe 的平均延迟略差(更高),但在非常高的 CPU 线程数下,平均延迟明显更好(更低)。
4KB 随机 99% 尾部延迟
到目前为止,我们没有看到强有力的证据表明部署多个 OSD 每 NVMe 具有显著优势,除非在非常高的 CPU 线程比率下。但是,有一个情况,我们仍然看到显著的优势。运行多个 OSD 每 NVMe 可以始终如一地降低几乎所有情况下的尾部延迟。
99% 尾部延迟的改进是巨大的,在某些情况下,运行 2 个 OSD 每 NVMe 可以将 99% 延迟降低一半。虽然这里没有显示,但 99.9% 延迟的改进更好。虽然对于大多数 Reef 部署,运行多个 OSD 每 NVMe 可能不会显示出显著的性能优势,但它可能会显示出显著的尾部延迟优势。但是……有成本吗?
4KB 随机 CPU 使用率
尽管通过 numactl 限制 OSD 只能使用一定数量的 CPU 线程,但 2 OSD 每 NVMe 配置始终使用的 CPU 比 1 OSD 每 NVMe 配置多。让我们进一步了解这如何转化为 CPU 效率。
我们之前看到,两种 OSD 配置在最多约 16 个 CPU 线程时表现相似。之后,2 个 OSD 每 NVMe 配置继续扩展,而单个 OSD 配置达到了峰值。我们还看到 2 个 OSD 每 NVMe 配置具有更低的尾部延迟。在这里,我们看到每个 CPU 线程在 2 个 OSD 每 NVMe 配置中更努力地工作,以实现相同的 IOPS,尽管有这些其他优势。这可能会导致更高的功耗和更大的发热量。请注意:这里报告的随机写入结果考虑了复制,以匹配我们去年秋天发布的 Pacific 的结果 此处。虽然测试配置与去年秋天略有不同,但我们似乎在这些 Reef 测试中实现了适度的效率改进。
4KB 随机内存使用率
虽然 2 OSD 每 NVMe 情况下的 CPU 使用率显著增加,但内存使用率的增加相对较小。通常,大约有 3-6% 的惩罚,而使用 1 OSD 每 NVMe。两种配置都没有使用为该数据集大小提供的所有内存。
结论
我们之前看到,多个 OSD 每 NVMe 的性能优势在 Nautilus 和 Pacific 版本的 Ceph 之间发生了显著变化。现在 Reef 已经发布,我们进行了更深入的分析,并注意到在我们的测试系统上存在一些细微的优势和劣势:
| 1 OSD 每 NVMe 优点 | 2 OSDs 每 NVMe 优点 |
|---|---|
| + 更简单的配置 | + 略微更好的大型读取吞吐量 |
| + 更好的大型写入吞吐量 | + 在 CPU 密集型时更好的 IOPS |
| + 在 CPU 饥饿时略微更好的 IOPS | + 在 CPU 密集型时更好的延迟 |
| + 更好的 CPU 效率 | + 显著更好的尾部延迟 |
| + 略微更好的内存使用率 | |
其他硬件配置可能会根据 CPU、闪存或其他性能特征显示不同的扩展行为。我相信这些结果应该提供一个关于在现代 Ceph 版本中运行 2 OSD 每 NVMe 配置的潜在优势和劣势的一般图景。与往常一样,最好的方法是自己进行测试,看看您的发现是否与我们在这里看到的内容相符。感谢您的阅读,如果您有任何问题或想进一步讨论 Ceph 性能,请随时 联系。