【问题标题】:Does it make sense to use a pool of Actors?使用 Actor 池有意义吗?
【发布时间】:2010-12-31 11:07:10
【问题描述】:

我只是在学习并且非常喜欢 Actor 模式。我现在正在使用 Scala,但我对总体架构风格很感兴趣,因为它用于 Scala、Erlang、Groovy 等。

我正在考虑的情况是我需要同时做一些事情,例如,让我们说“运行一份工作”。

使用线程,我将创建一个线程池和一个阻塞队列,并让每个线程轮询阻塞队列,并在作业进出队列时处理它们。

对于演员,处理这个问题的最佳方法是什么?创建一个演员池并以某种方式向他们发送包含作业或作业的消息是否有意义?也许和“协调员”演员一起?

注意:我忘记提及的案例的一个方面是:如果我想限制我的应用程序将同时处理的作业数量怎么办?也许有配置设置?我在想一个游泳池可能会更容易做到这一点。

谢谢!

【问题讨论】:

  • 是的,限制在任务列表中工作的参与者数量是有意义的。至少 Erlang 为您提供了足够的并发性,您可以通过使用它们产生足够多的进程来耗尽大部分系统资源。
  • 我试图在这里以更集中、更具体、更具体的方式重新表述这个问题:stackoverflow.com/questions/2312195/…

标签: scala concurrency erlang actor


【解决方案1】:

池是您在创建和拆除资源的成本很高时使用的一种机制。在 Erlang 中情况并非如此,因此您不应该维护一个池。

您应该根据需要生成进程,并在完成处理后销毁它们。

【讨论】:

  • 谢谢,但是如果我想限制我的应用程序将同时处理的作业数量怎么办?也许有配置设置?我在想游泳池可以很容易地做到这一点。
  • @Avi:我认为你需要在这里做出区分。 “池”通常是指(至少对我而言)实际上保留参与者/进程并重用它们。在 Erlang 中你不需要这样做,你可以把它们扔掉并产生新的。当然,您可以实现一个“全局计数器”(以服务器进程的形式、在 ets 表中等),您可以在生成另一个作业进程之前对其进行轮询。事实上,你确实需要一些这样的工具来实现负载控制......
  • @Zed:很好,谢谢。也许我应该问“什么是限制参与者并发的好方法?”
  • 您也许可以使用 Actor.mailboxSize 来获得您正在寻找的那种约束
  • 这种方法似乎也是实现您所寻求的一种方式:stackoverflow.com/questions/1007010/…
【解决方案2】:

有时,限制您在大型任务列表上同时运行的工作进程的数量是有意义的,因为生成该进程以完成的任务涉及资源分配。至少进程会耗尽内存,但它们也可以保留打开的文件和/或套接字,这些文件和/或套接字往往仅限于数千个,并且一旦用完就会惨遭失败且不可预测。

要拥有一个拉动驱动的任务池,可以生成 N 个请求任务的链接进程,并且一方面给它们一个可以生成_monitor 的函数。一旦被监控的进程结束,他们就会回来执行下一个任务。具体需求驱动细节,但这是一种方法的概要。

我会让每个任务产生一个新进程的原因是进程确实有一些状态,从一个干净的状态开始是很好的。设置进程的最小堆大小是一种常见的微调,以最大限度地减少其生命周期内所需的 GC 数量。它也是一种非常有效的垃圾回收,可以为一个进程释放所有内存并为下一个任务启动一个新内存。

这样使用两倍数量的进程是不是感觉很奇怪?这是你在 Erlang 编程中需要克服的一种感觉。

【讨论】:

  • 非常有趣,谢谢!我可能会将其标记为“已接受”的答案,我必须考虑一下。
【解决方案3】:

没有适用于所有情况的最佳方法。决定取决于作业的数量、持续时间、到达时间和所需的完成时间。

仅生成 Actor 和使用池之间最明显的区别在于,在前一种情况下,您的工作将几乎同时完成,而在后一种情况下,完成时间将及时分布。不过平均完成时间是一样的。

使用演员的优点是编码简单,因为它不需要额外的处理。权衡是您的参与者将争夺您的 CPU 内核。无论您使用何种编程范式,您都无法拥有比 CPU 内核(或 HT 等)更多的并行作业。

例如,假设您需要执行 100,000 个作业,每个作业需要一分钟,结果将于下个月到期。你有四个核心。您会派生出 100,000 个演员,每个演员争夺资源一个月,还是将您的工作排队,一次执行四个?

作为一个反例,想象一个 Web 服务器在同一台机器上运行。如果您有五个请求,您是希望在 T 时间内为四个用户提供服务,在 2T 时间内为一个用户提供服务,还是在 1.2T 时间内为所有五个用户提供服务?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-04
    • 2020-12-05
    • 2015-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-03
    • 2013-04-28
    相关资源
    最近更新 更多