跳到主要内容

集群大小调整案例研究 - 镜像队列 第 1 部分

·13 分钟阅读
Jack Vanlightly

在本系列调整大小的第一篇文章中,我们介绍了 AWS ec2 上的工作负载、集群和存储卷配置。在本文中,我们将使用镜像队列运行大小调整分析。

我们的大小调整分析的第一阶段将是评估我们的每个集群和存储卷可以轻松处理哪些强度,以及哪些强度过高。

所有测试均使用以下策略

  • ha-mode: exactly
  • ha-params: 2
  • ha-sync-mode: manual

理想条件 - 增长强度测试

在之前的文章中,我们讨论了运行基准测试的选项。您可以使用以下命令以这些强度运行此工作负载

bin/runjava com.rabbitmq.perf.PerfTest \
-H amqp://guest:guest@10.0.0.1:5672/%2f,amqp://guest:guest@10.0.0.2:5672/%2f,amqp://guest:guest@10.0.0.3:5672/%2f \
-z 1800 \
-f persistent \
-q 1000 \
-c 1000 \
-ct -1 \
--rate 50 \
--size 1024 \
--queue-pattern 'perf-test-%d' \
--queue-pattern-from 1 \
--queue-pattern-to 100 \
--producers 200 \
--consumers 200 \
--consumer-latency 10000 \
--producer-random-start-delay 30

只需更改 --rate 参数为您需要的每个测试的速率,并记住它是每个发布者的速率,而不是总的组合速率。由于消费者处理时间(消费者延迟)设置为 10 毫秒,我们还需要增加消费者数量以适应更高的发布速率。

在运行 PerfTest 之前,您需要创建一个策略,将创建的队列转换为镜像队列,其中包含一个主队列和您希望测试的镜像数量。

io1 - 高性能 SSD

Fig 1. Increasing intensity tests and the io1 volume
图 1. 增加强度测试和 io1 卷

Fig 2. End-to-end latencies for clusters 3x36, 3x16, 5x16 and 7x16.
图 2. 集群 3x36、3x16、5x16 和 7x16 的端到端延迟。

Fig 3. End-to-end latencies for clusters 5x8, 7x8, and 9x8. Note that the 99th percentile for the 5x8 reached 30 seconds.
图 3. 集群 5x8、7x8 和 9x8 的端到端延迟。请注意,5x8 的第 99 个百分位数达到了 30 秒。

不同的集群设法达到了不同的强度,但除了一个测试外,所有测试都保持在 99% 百分位数端到端延迟要求 1 秒以下。

大多数测试的限制因素是 CPU,因此拥有最多 CPU 的配置表现最佳也就不足为奇了。有趣的是,拥有第二高总 vCPU 数量的 3 节点、36 vCPU 集群 (3x36) 表现不佳,甚至低于 7x8 vCPU 集群。实际上,3x36 集群上的 CPU 使用率没有超过 50%,Erlang 似乎无法有效地利用每个 Broker 的所有 36 个 vCPU(稍后会详细介绍)。

磁盘吞吐量没有接近容量,但在所有配置中,IOPS 都达到了 8000-9000,写入大小约为 5-7kb。网络带宽保持在低于 1gbit 的水平,这在所有 VM 的限制范围内。

底部吞吐量集群 (3x16):

Fig 4. CPU and Network for the poorest performing cluster (3x16).
图 4. 性能最差集群 (3x16) 的 CPU 和网络。

Fig 5. Disk usage for the poorest performing cluster (3x16).
图 5. 性能最差集群 (3x16) 的磁盘使用情况。

顶部吞吐量集群 (7x16)

Fig 6. CPU and network for the top performing cluster (7x16).
图 6. 性能最佳集群 (7x16) 的 CPU 和网络。

Fig 7. Disk usage for the top performing cluster (7x16).
图 7. 性能最佳集群 (7x16) 的磁盘使用情况。

洞察:性能较低的 3x16 集群的磁盘写入吞吐量略高于性能最佳的 7x16 集群。这是因为如果消息在 fsync 执行时已被消费,则不会将消息持久化到磁盘。因此,当消费者跟上时,磁盘写入会更少。如果我们查看 25k msg/s 测试,这是两者都可以处理的最高值,我们看到 3x16 集群的第 95 个百分位数延迟约为 250 毫秒,而 7x16 集群约为 4 毫秒。Fsync 大约每 200 毫秒发生一次。因此,性能更高的集群执行的写入操作更少。

匹配目标吞吐量排行榜

每个集群大小设法达到的最高吞吐量,其中它精确地交付了目标速率。

  1. 集群:7 节点,16 个 vCPU (c5.4xlarge)。速率:65k msg/s
  2. 集群: 5 节点,16 个 vCPU (c5.4xlarge)。速率: 45k msg/s
  3. 集群: 9 节点,8 个 vCPU ( c5.2xlarge)。速率: 45k msg/s
  4. 集群: 7 节点,8 个 vCPU (c5.2xlarge)。速率: 40k msg/s
  5. 集群: 3 节点,36 个 vCPU (c5.9xlarge)。速率: 30k msg/s
  6. 集群: 5 节点,8 个 vCPU (c5.2xlarge)。速率: 20k msg/s
  7. 集群: 3 节点,16 个 vCPU (c5.4xlarge)。速率: 20k msg/s

我们看到向上和向外扩展的中间地带为我们提供了最佳吞吐量,但向外扩展也做得很好。向上扩展不太好。

在最高吞吐量下,每 1000 msg/s 每月成本排行榜。

  1. 集群: 5 节点, 16 个 vCPU。成本:134 美元 (45k msg/s)
  2. 集群: 7 节点,16 个 vCPU。成本:140 美元 (65k msg/s)
  3. 集群: 7 节点, 8 个 vCPU。成本:170 美元 (40k msg/s)
  4. 集群: 3 节点,16 个 vCPU。成本:182 美元 (20k msg/s)
  5. 集群: 3 节点,36 个 vCPU。成本:182 美元 (30k msg/s)
  6. 集群: 9 节点,8 个 vCPU。成本:194 美元 (45k msg/s)
  7. 集群: 5 节点, 8 个 vCPU。成本:242 美元 (20k msg/s)

在 30k msg/s 目标速率下,每 1000 msg/s 每月成本排行榜。

  1. 集群:3 节点,36 个 vCPU。成本:183 美元
  2. 集群: 5 节点,16 个 vCPU。成本:202 美元
  3. 集群: 7 节点,8 个 vCPU。成本:226 美元
  4. 集群: 9 节点,8 个 vCPU。成本:291 美元
  5. 集群: 7 节点,16 个 vCPU。成本:307 美元

虽然使用较小 VM 进行横向扩展具有不错的吞吐量,但由于我们的磁盘是最昂贵的项目,因此被削弱了。由于磁盘很昂贵,因此最具成本效益的集群是实例最少的集群,但是,这个 3x36 集群仅勉强应付了这种理想条件测试中的峰值,在更困难的测试中不太可能坚持下去。因此,如果我们忽略 3x36 集群,最具成本效益的是向上和向外扩展的中间地带。

我们真的需要那些昂贵的 io1 SSD 吗?我们不需要它们来获得 IO 吞吐量,但 10000 IOPS 几乎已完全利用。3000 IOP gp2 能否处理更高的强度?

gp2 - 通用 SSD

Fig 8. Increasing intensity test with the gp2 volume.
图 8. 使用 gp2 卷增加强度测试。

Fig 9. End-to-end latencies for clusters 3x36, 3x16, 5x16 and 7x16.
图 9. 集群 3x36、3x16、5x16 和 7x16 的端到端延迟。

Fig 10. End-to-end latencies for clusters 5x8, 7x8, and 9x8.
图 10. 集群 5x8、7x8 和 9x8 的端到端延迟。

同样,不同的集群设法实现了不同的吞吐量,但都在端到端延迟要求范围内。

我们有了一个新的赢家,使用 gp2 卷:9x8 集群,其次是 7x8 集群。7x16 和 5x16 在达到并超过其最大容量后,吞吐量出现了一些波动。底部两个集群仍然相同:3x36 和 3x16 集群。

那么 RabbitMQ 如何处理较低的 IOPS 卷呢?

底部吞吐量集群 (3x16)

Fig 11. Disk usage for the poorest performing cluster (3x16).
图 11. 性能最差集群 (3x16) 的磁盘使用情况。

我们从 5000 msg/s 速率及以上达到了 3000 IOPS 限制。随着测试的进行,为了应对更大的磁盘吞吐量,IO 大小增加了。因此,看起来我们根本不需要所有这些 IOPS。

顶部吞吐量集群 (9x8)

Fig 12. Disk usage for the top performing cluster (9x8).
图 12. 性能最佳集群 (9x8) 的磁盘使用情况。

对于性能最高的集群,情况完全相同 - RabbitMQ 调整为较低的可用 IOPS。

匹配目标吞吐量排行榜

  1. 集群: 9 节点,8 个 vCPU (c5.2xlarge)。速率:65k msg/s
  2. 集群: 7 节点,8 个 vCPU (c5.2xlarge)。速率: 50k msg/s
  3. 集群: 7 节点,16 个 vCPU (c5.4xlarge)。速率: 50k msg/s
  4. 集群: 5 节点,16 个 vCPU (c5.4xlarge)。速率: 40k msg/s
  5. 集群: 3 节点,36 个 vCPU (c5.9xlarge)。速率: 35k msg/s
  6. 集群: 5 节点,8 个 vCPU (c5.2xlarge)。速率: 35k msg/s
  7. 集群: 3 节点,16 个 vCPU (c5.4xlarge)。速率: 25k msg/s

这一次,横向扩展显然是最有效的。向上扩展不太好。

在最高吞吐量下,每 1000 条消息每月成本排行榜。

  1. 集群: 9 节点,8 个 vCPU。成本:48 美元 (65k msg/s)
  2. 集群: 7 节点,8 个 vCPU。成本:48 美元 (50k msg/s)
  3. 集群: 5 节点,8 个 vCPU。成本:49 美元 (35k msg/s)
  4. 集群: 3 节点,16 个 vCPU。成本:71 美元 (25k msg/s)
  5. 集群: 5 节点,16 个 vCPU。成本:74 美元 (40k msg/s)
  6. 集群: 7 节点,16 个 vCPU。成本:96 美元 (50k msg/s)
  7. 集群: 3 节点,36 个 vCPU。成本:103 美元 (35k msg/s)

在每顶部吞吐量成本方面,顺序为:核心计数降序,节点计数降序

在 30k msg/s 目标速率下,每 1000 条消息每月成本排行榜。

  1. 集群:5 节点,8 个 vCPU。成本:58 美元
  2. 集群: 7 节点,8 个 vCPU。成本:81 美元
  3. 集群:5 节点,16 个 vCPU。成本:98 美元
  4. 集群: 9 节点,8 个 vCPU。成本:104 美元
  5. 集群:3 节点,36 个 vCPU。成本:120 美元
  6. 集群: 7 节点,16 个 vCPU。成本:161 美元

在我们的 30k msg/s 目标速率下,5x8 是最佳选择。结论是,横向扩展较小的 VM 既能提供更好的性能,又能提供最佳的成本效益。原因是 gp2 卷相对便宜,并且我们不会像使用昂贵的 io1 卷那样因横向扩展而受到惩罚。

st1 - HDD

到目前为止,我们已经看到 RabbitMQ 通过根据需要调整到较低的 IOPS 来利用其可用的 IOPS。HDD 是为具有低 IOPS 的大型和顺序工作负载而构建的,因此 RabbitMQ 是否能够再次调整其磁盘操作,以进行更少但更大的磁盘操作?让我们看看。

Fig 13. Increasing intensity test with the st1 volume.
图 13. 使用 st1 卷增加强度测试。

Fig 14. End-to-end latencies for clusters 3x36, 3x16, 5x16 and 7x16.
图 14. 集群 3x36、3x16、5x16 和 7x16 的端到端延迟。

Fig 15. End-to-end latencies for clusters 5x8, 7x8 and 9x8.
图 15. 集群 5x8、7x8 和 9x8 的端到端延迟。

查看吞吐量,HDD 在最高吞吐量方面表现最佳,实际上达到了 70k msg/s 的最高强度。端到端延迟具有不同的模式。使用 SSD,延迟开始时非常小,然后随着强度的增加而增加。但是 HDD 的延迟从一开始就高得多,并且增长速度慢得多。

让我们看看 RabbitMQ 如何使用可用的 IOPS。

底部吞吐量集群 (3x16)

Fig 16. Disk usage for the poorest performing cluster (3x16).
图 16. 性能最差集群 (3x16) 的磁盘使用情况。

我们现在降至 500-600 IOPS,平均写入大小接近 50kb(忽略初始峰值)。IO 操作少得多,但大得多。IO 延迟更高。我们已经从 0.5 毫秒 (io1)、2 毫秒 (gp2) 增加到 10 毫秒 (st1),这可能是 IO 大小和存储驱动器快速执行随机 IO 能力的组合。稍后,我们将比较三种磁盘类型的端到端延迟。

顶部吞吐量集群 (9x8)

Fig 17. Disk usage for the top performing cluster (9x8).
图 17. 性能最佳集群 (9x8) 的磁盘使用情况。

吞吐量排行榜

只有三种尺寸能够达到其目标,其余尺寸始终不足,即使它们的吞吐量在每次测试中都在攀升。我们可能可以通过不同的发布者确认飞行中限制来提高吞吐量,更高的限制可能有利于更高延迟的 HDD。

能够达到其目标的获胜者是

  1. 集群:9 节点,8 个 vCPU (c5.2xlarge)。速率:70k msg/s
  2. 集群: 7 节点,16 个 vCPU (c5.4xlarge)。速率: 65k msg/s
  3. 集群: 7 节点,8 个 vCPU (c5.2xlarge)。速率: 55k msg/s

其余的在每次测试中都未能达到其目标,但在测试进行过程中仍然显示出更高的吞吐量

  1. 集群: 5 节点,16 个 vCPU (c5.4xlarge)。速率: 55k msg/s
  2. 集群: 5 节点,8 个 vCPU (c5.2xlarge)。速率: 43k msg/s
  3. 集群: 3 节点,36 个 vCPU (c5.9xlarge)。速率: 35k msg/s
  4. 集群: 3 节点,16 个 vCPU (c5.4xlarge)。速率: 29k msg/s

对于 HDD,一切都与横向扩展有关,而不是向上扩展。 

在最高速率下,每 1000 条消息每月成本排行榜。

  1. 集群: 5 节点,8 个 vCPU。 成本:65 美元 (43k msg/s)
  2. 集群: 7 节点,8 个 vCPU。 成本:71 美元 (55k msg/s)
  3. 集群: 9 节点,8 个 vCPU。 成本:72 美元 (70k msg/s)
  4. 集群: 5 节点,16 个 vCPU。 成本:73 美元 (55k msg/s)
  5. 集群: 3 节点,16 个 vCPU。 成本:83 美元 (29k msg/s)
  6. 集群: 7 节点,16 个 vCPU。 成本:97 美元 (65k msg/s)
  7. 集群: 3 节点,36 个 vCPU。 成本:121 美元 (35k msg/s)

在 30k msg/s 目标速率下,每 1000 条消息每月成本排行榜。

  1. 集群:5 节点,8 个 vCPU。 成本:93 美元
  2. 集群: 7 节点,8 个 vCPU。 成本:131 美元
  3. 集群: 5 节点,16 个 vCPU。 成本:134 美元
  4. 集群:3 节点,36 个 vCPU。 成本:142 美元
  5. 集群: 9 节点,8 个 vCPU。 成本:168 美元
  6. 集群: 7 节点,16 个 vCPU。 成本:211 美元

就其最高吞吐量而言,显然较小的 VM 最具成本效益。但是,当考虑 30k msg/s 的目标时,横向扩展/向上扩展的中间地带显示出最佳结果。横向扩展(性能和成本最佳,但 st1 卷有点昂贵)与成本之间再次存在一些冲突。因此,中间地带获胜。

端到端延迟和三种卷类型

在这些测试中,我们将端到端延迟视为消息发布和消费之间的时间。如果我们查看 30k msg/s 的目标速率和 7x16 集群类型,我们看到

io1

Fig 18. 50th and 75th percentile latencies for io1 at 30k msg/s.
图 18. io1 在 30k msg/s 时的第 50 和第 75 百分位数延迟。

Fig 19. 50th, 75th, 95th, 99th and 99.9th percentile latencies for io1 at 30k msg/s.
图 19. io1 在 30k msg/s 时的第 50、75、95、99 和 99.9 百分位数延迟。

gp2

Fig 20. 50th and 75th percentile latencies for gp2 at 30k msg/s.
图 20. gp2 在 30k msg/s 时的第 50 和第 75 百分位数延迟。

Fig 21. 50th, 75th, 95th, 99th and 99.9th percentile latencies for gp2 at 30k msg/s.
图 21. gp2 在 30k msg/s 时的第 50、75、95、99 和 99.9 百分位数延迟。

st1

Fig 22. 50th and 75th percentile latencies for st1 at 30k msg/s.
图 22. st1 在 30k msg/s 时的第 50 和第 75 百分位数延迟。

Fig 23. 50th, 75th, 95th, 99th and 99.9th percentile latencies for st1 at 30k msg/s.
图 23. st1 在 30k msg/s 时的第 50、75、95、99 和 99.9 百分位数延迟。

我们看到 io1 提供了最佳的延迟,直到第 95 个百分位数,之后它或多或少与 gp2 匹配。st1 HDD 显示出更高的延迟,但仍在我们的 1 秒目标范围内。

CPU 利用率和 36 vCPU VM

在 8 和 16 vCPU(CPU 线程)实例中,CPU 似乎是瓶颈。一旦 CPU 使用率超过 90%,我们就停止看到吞吐量的任何进一步增加。但是,36 vCPU 实例往往总是这样

Fig 24. CPU utilisation on the 3x36 cluster.
图 24. 3x36 集群上的 CPU 利用率。

CPU 利用率和 Erlang 并不总是那么直接。Erlang 调度器在他们认为这样做更有效时会进行忙等待。这意味着,调度器不是休眠,而是坐在一个繁忙的循环中,利用 CPU,同时等待新的工作要做。这可能会让人觉得 Erlang 应用程序正在做很多工作,使用 CPU,但实际上它只是在等待工作。

在这种特殊情况下,36 个 vCPU 只是浪费。我们已经看到,与横向扩展的较小 VM 相比,它们更昂贵且交付的结果更差。

增加强度基准测试 - 结论

到目前为止的结论是

  • 只有当我们真正关心端到端延迟时,昂贵的 io1 才值得。
  • 廉价的 gp2 提供了性能和成本的最佳组合,是大多数工作负载的最佳选择。请记住,我们使用了 1TB 大小,它没有突发 IOPS,并且有 250 MiBs 的限制(我们从未达到)。
  • 对于廉价存储卷,横向扩展较小的 8 vCPU VM 在成本效益和性能方面都是最佳的。
  • 对于昂贵的卷,采用横向扩展和向上扩展的中间地带最具成本效益。
  • CPU 利用率似乎是 16 和 8 vCPU 上的限制因素。大型 36 vCPU 实例的使用率没有超过 60%,但也没有达到磁盘或网络限制。Erlang 只是无法有效地使用那么多核心。

在 30k msg/s 吞吐量下,每 1000 msg/s 每月成本的前 5 名配置

  1. 集群:5 节点,8 个 vCPU,gp2 SDD。成本:58 美元
  2. 集群: 7 节点,8 个 vCPU,gp2 SDD。成本:81 美元
  3. 集群:5 节点,8 个 vCPU,st1 HDD。 成本:93 美元
  4. 集群:5 节点,16 个 vCPU,gp2 SDD。成本:98 美元
  5. 集群: 9 节点,8 个 vCPU,gp2 SDD。成本:104 美元

我们仅在理想条件下进行了测试...

我们从 21 种不同的集群配置在 15 种不同的工作负载强度下收集了大量数据。我们认为到目前为止,我们应该选择在中等到大型集群中使用廉价 gp2 卷上的小型 VM。但这测试的是队列为空或接近为空的理想场景,在这种情况下,RabbitMQ 以其最佳性能运行。接下来,我们将运行更多测试,以确保尽管 Broker 丢失和队列积压发生,我们选择的集群大小仍然能够交付我们需要的性能。接下来我们测试弹性。

© . All rights reserved.