Golang工作人员池的最佳规模

时间:2017-12-24 07:22:22

标签: go optimization parallel-processing goroutine worker-pool

我正在构建一个使用"工作池"的Golang应用程序。 goroutines,最初我开始创建一些工作池。我想知道多核处理器中的最佳工作数是多少,例如在具有4个内核的CPU中?我目前正在使用以下方法:

list

完整的实施在

之下
  

job.NewWorkerPool(maxWorkers)   和      module.Dispatcher.Run(jobQueue)

我使用工作池的用例:我有一个接受请求并调用多个外部API并将其结果聚合到一个响应中的服务。每次通话都可以独立完成,因为结果的顺序并不重要。我将调用分派给工作池,每个调用都以异步方式在一个可用的goroutine中完成。我的请求"一旦完成工作线程,线程就会在获取和聚合结果时继续监听返回通道。完成所有操作后,最终的聚合结果将作为响应返回。由于每个外部API调用可能呈现可变响应时间,因此某些调用可以比其他调用更早完成。根据我的理解,以并行方式进行操作在性能方面会更好,就好像以同步方式一样接一个地调用每个外部API

1 个答案:

答案 0 :(得分:3)

示例代码中的注释表明您可能会混淆GOMAXPROCS和工作池的两个概念。这两个概念在Go中完全不同。

  1. GOMAXPROCS设置Go运行时将使用的最大CPU线程数。默认为系统上找到的CPU核心数,几乎不应更改。我唯一能想到改变这种情况的方法是,如果你想明确限制Go程序因某些原因使用少于可用的CPU,那么你可以将它设置为1,例如,即使在4上运行核心CPU。这在极少数情况下应该是重要的。

    TL; DR; 永远不要手动设置runtime.GOMAXPROCS

  2. Go中的工作池是一组goroutine,它们在到达时处理作业。 Go中有不同的处理工作池的方法。

    您应该使用多少工人?没有客观的答案。可能唯一的方法就是对各种配置进行基准测试,直到找到符合要求的配置为止。

    作为一个简单的例子,假设您的工作池正在执行非常耗费CPU的事情。在这种情况下,您可能需要每个CPU一个工作程序。

    作为一个更可能的例子,让我们说你的员工正在做更多的I / O限制 - 例如阅读HTTP请求或通过SMTP发送电子邮件。在这种情况下,您可以合理地处理每个CPU数十甚至数千名工作人员。

    然后还有你是否应该使用工作池的问题。 Go中的大多数问题根本不需要工作池。我曾经参与过几十个生产Go程序,从来没有在其中任何一个中使用过工作池。我也写了很多次一次性使用Go工具,并且只用了一次工作池。

  3. 最后,GOMAXPROCS和工作池相关的唯一方式与goroutines与GOMAXPROCS的关联方式相同。来自the docs

      

    GOMAXPROCS变量限制了可以同时执行用户级Go代码的操作系统线程数。代表Go代码在系统调用中可以阻塞的线程数没有限制;那些不计入GOMAXPROCS限制。该软件包的GOMAXPROCS函数可以查询和更改限制。

    从这个简单的描述中,很容易看出可能会有更多(可能是数十万......或更多)goroutines比GOMAXPROCS - GOMAXPROCS仅限制如何许多"操作系统线程可以同时执行用户级Go代码" - 目前没有执行用户级Go代码的goroutines不计数。在I / O绑定的goroutine(例如等待网络响应的那些)中,不执行代码。因此,理论上最大数量的goroutine仅受系统可用内存的限制。