使用 shoryuken 进行后台作业时如何确定并发性(线程)?

How to determine concurrency (threads) while using shoryuken for background jobs?

在我的 Ruby on Rails 应用程序中,我使用 shoryouken 进行后台处理。我的应用程序中有很多 sqs 队列 (6-7)。其中一个队列有 2000-3000 个作业,worker 处理这些 2-3k 个作业大约需要 3 个小时,默认并发数为 25。因此,我们可以根据哪些因素来决定增加并发数(即线程来处理作业)。如果问题中有任何不清楚的地方,请发表评论。

三个主要因素是

  1. 内核数
  2. 工作类型 - I/O 或 CPU 绑定
  3. 服务器
  4. 上是否有其他应用程序或进程运行

理想情况下,cpu 绑定任务将线程数保持为 cpu 核心数。

对于I/O绑定任务,它需要进行基准测试并计算I/O的等待时间,然后您可以决定最佳值。对于粗略估计,如果你有 4 个内核而不是 I/O 绑定任务,你必须保持最多 8 个线程。

如果您在 rails 应用 运行 上安装了相同的应用,那么您将需要减少内核数量。

如果您的系统不支持,增加内核数量不会提高您的性能。

参考:http://baddotrobot.com/blog/2013/06/01/optimum-number-of-threads/

Concurrency defaults to 25,但可以通过更改 shoryuken.yml 配置(见下文)或添加并发参数来更改:shoryuken -c {desiredCount}

concurrency: 25  # Update with your desired value.
delay: 25        # The delay in seconds to pause a queue when it's empty. Default 0
queues:
  - [high_priority, 6]
  - [default, 2]
  - [low_priority, 1]

您将需要测试最佳性能值,因为随着并发线程数量的增加,您将 运行 陷入 I/O 和 CPU 瓶颈。达到实例的最佳值后,您需要增加实例数 运行 执行此作业或升级实例。

如果瓶颈存在于您的数据库或其他资源上,您将需要相应地进行调整。 (不太可能是这种情况,但为了彻底起见包括在内)

编辑:优化性能

针对您关于优化线程数的问题,quickest/best 确定最佳并发值的方法是更改​​并发并测量 real-world 吞吐量。还有其他方法,但性能的黄金法则是始终在现场生产环境中进行测量。综合基准​​仅在反映 real-time 性能的情况下才有用。 (另请参阅:premature optimization)。

在这种情况下,您很容易会想太多(话又说回来,想太多是开发中长期存在的问题)。只需使用适当的指标(CPU 利用率、内存利用率、每分钟完成的作业数)进行测量,并更改线程数,直到您最大化吞吐量或 运行 进入瓶颈。

如果您的任务受到 CPU 限制,您会看到 CPU 利用率达到最大值。如果您的任务受到 I/O 限制,您会发现在某个时间点后,并发线程的增加并没有转化为吞吐量的增加,即使您的 CPU 利用率没有上升。

当您 reading/writing 的任何资源无法满足您的 CPU 需求时,就会出现 I/O 瓶颈。这包括系统资源(内存、磁盘 space)、您的数据库性能(DB CPU 利用率、read/write 限制)以及您连接的其他 API。网络容量也是一个理论上的瓶颈,但如果它是你足够大,可以聘请在这方面有经验的人。因为发生这种情况的方式有很多种,所以找出瓶颈的唯一真正方法是进行适当的监控。

回复:公式,简而言之,在这种情况下,没有一种公式可以使用。长答案可能是肯定的,但您会在收集计算它所需的所有值的过程中得出最佳值。

编辑 2:并发、延迟和吞吐量

我意识到我忘了再添加一条建议。当您处理用户不等待的后台任务时,您的吞吐量(每单位时间的作业数)是您想要优化的唯一。不要针对个别工作时间进行优化。这也意味着您无法分析当前(可能 un-bound)的性能并获得有用的数据,因为 bottlenecks/constraints 取决于目标。针对吞吐量存在的约束与针对单个任务时间存在的约束不同。

(从技术上讲,您的并发设置是您当前的约束)