动态找到最佳Actor数量
Dynamically find the optimal number of Actors
我有一个 master actor,它通过将消息委托给它的 children 来处理消息,我想找到可以最快处理这些消息的最佳 children 数量。 children 的数量应该随着时间的推移而变化,因为服务器上的负载从其他需要资源的应用程序发生变化。是否有一些已经流行的路由器或模式可以做到这一点?
编辑: 我有非常具体的需要来做这个,每个演员负责处理它启动的一个进程,该进程完成所有计算密集型工作,所以演员自己没有做任何实际工作,它们只是为了并发而存在。这与其说是优化 akka 本身或 jvm 上的代码,不如说是一个问题,而是要并行 运行 多少个应用程序实例才能获得最佳性能。这完全取决于有多少工人。如果处理器数量多于可用内核数量,那么我会开始看到性能大幅下降,当其他用户开始使用我的应用程序 运行 正在运行的服务器时,就会发生这种情况。通常我不会关心这种优化,但该应用程序正在 运行 进行大量模拟,这可能需要几天甚至几个月的时间。这个问题在我工作的(工程)领域非常重要,在这个领域中模拟可能需要很长时间。通常你不会像这样争夺资源,但这是我无法控制的情况。
请理解以下none对我有用。
- 建议将服务器专用于我的应用程序 - 我无法执行此操作。
- 要限制消息 - 进程本身在空闲时占用 CPU,启动和终止它们也会分配 cpu,因为它们通过 tcp
连接到其他服务器
对于赏金答案,必须解决如何天真地控制响应处理消息时间的某些庄园中的参与者数量。消息总是相同的工作量,所以这不是一个可怕的策略,虽然不是最好的,但就像我说的,任何小的优化都是值得的,如果对我来说,虽然我理解一般来说这不是一个好方法。
首先,强烈不建议屏蔽actor(你可以在Akka docs) - you can always delegate blocking operation to the Future
executing inside separate ForkJoinPool
, but best is to use async APIs (and reactive-complient solutions) of course. If your blocking is managed中阅读(简单地说,用scala.concurrent.blocking
包裹)FJ-Pool会自动适应负载,并使用最大 CPU(请参阅下文如何控制此最大值);但是,创建补偿线程可能会花费您很多。因此,"reactive" 比使用 FJ 更好。
那么剩下的就是选择正确的池大小。通常,人们只是将它设置为等于处理器的数量,因此分配 CPU 时间的责任交给了 JVM+OS。但是,JVM 允许您对系统业务进行调整,请参阅 OperatingSystemMXBean, ThreadMXBean。
所以你可以让工作人员的数量等于处理器的数量,但是当 OS 太忙时你可以忽略其中的一些。这是一种非常正常的做法,因为(目前)活跃工作人员的数量永远不会超过处理器的数量。
所以使用这个想法你可以在你的系统上创建某种背压。参见 Akka 的 Akka and BackPressure and Throttling。背压和节流之间的主要区别在于背压会通知外部系统您正忙 - 您不必将消息存储在缓冲区中,因此您也可以控制内存消耗。
讨论如何根据当前统计数据准确选择(准确地说,从最大值动态减少)值 - Queuing Theory 可能会有所帮助。
我认为您不会为 Actor
的空邮箱支付太多罚款,因此没有真正需要减少演员数量。
如果你接受这个,那么工作池的任何基本路由器都可以为你工作,有一些上限基于你希望这个参与者在给定时间激活的 cores/threads 数量,即:
http://doc.akka.io/docs/akka/snapshot/scala/routing.html#SmallestMailboxPool
另一种方法可能是创建一个 actor 来处理每个传入的任务,这些任务将在处理输入后终止。为此,您只需在传入消息的处理程序中创建参与者,并让该参与者在完成其工作并提供结果后自行停止。
除了这些策略之外的任何优化都应该在您尝试过这些策略并发现它们不足之后才进行——不要过早地优化。
考虑使用 https://github.com/iheartradio/kanaloa
一组使用 Akka actor 实现的工作调度器,具有自动缩放、背压、断路器和实时监视器。
我有一个 master actor,它通过将消息委托给它的 children 来处理消息,我想找到可以最快处理这些消息的最佳 children 数量。 children 的数量应该随着时间的推移而变化,因为服务器上的负载从其他需要资源的应用程序发生变化。是否有一些已经流行的路由器或模式可以做到这一点?
编辑: 我有非常具体的需要来做这个,每个演员负责处理它启动的一个进程,该进程完成所有计算密集型工作,所以演员自己没有做任何实际工作,它们只是为了并发而存在。这与其说是优化 akka 本身或 jvm 上的代码,不如说是一个问题,而是要并行 运行 多少个应用程序实例才能获得最佳性能。这完全取决于有多少工人。如果处理器数量多于可用内核数量,那么我会开始看到性能大幅下降,当其他用户开始使用我的应用程序 运行 正在运行的服务器时,就会发生这种情况。通常我不会关心这种优化,但该应用程序正在 运行 进行大量模拟,这可能需要几天甚至几个月的时间。这个问题在我工作的(工程)领域非常重要,在这个领域中模拟可能需要很长时间。通常你不会像这样争夺资源,但这是我无法控制的情况。
请理解以下none对我有用。
- 建议将服务器专用于我的应用程序 - 我无法执行此操作。
- 要限制消息 - 进程本身在空闲时占用 CPU,启动和终止它们也会分配 cpu,因为它们通过 tcp 连接到其他服务器
对于赏金答案,必须解决如何天真地控制响应处理消息时间的某些庄园中的参与者数量。消息总是相同的工作量,所以这不是一个可怕的策略,虽然不是最好的,但就像我说的,任何小的优化都是值得的,如果对我来说,虽然我理解一般来说这不是一个好方法。
首先,强烈不建议屏蔽actor(你可以在Akka docs) - you can always delegate blocking operation to the Future
executing inside separate ForkJoinPool
, but best is to use async APIs (and reactive-complient solutions) of course. If your blocking is managed中阅读(简单地说,用scala.concurrent.blocking
包裹)FJ-Pool会自动适应负载,并使用最大 CPU(请参阅下文如何控制此最大值);但是,创建补偿线程可能会花费您很多。因此,"reactive" 比使用 FJ 更好。
那么剩下的就是选择正确的池大小。通常,人们只是将它设置为等于处理器的数量,因此分配 CPU 时间的责任交给了 JVM+OS。但是,JVM 允许您对系统业务进行调整,请参阅 OperatingSystemMXBean, ThreadMXBean。
所以你可以让工作人员的数量等于处理器的数量,但是当 OS 太忙时你可以忽略其中的一些。这是一种非常正常的做法,因为(目前)活跃工作人员的数量永远不会超过处理器的数量。
所以使用这个想法你可以在你的系统上创建某种背压。参见 Akka 的 Akka and BackPressure and Throttling。背压和节流之间的主要区别在于背压会通知外部系统您正忙 - 您不必将消息存储在缓冲区中,因此您也可以控制内存消耗。
讨论如何根据当前统计数据准确选择(准确地说,从最大值动态减少)值 - Queuing Theory 可能会有所帮助。
我认为您不会为 Actor
的空邮箱支付太多罚款,因此没有真正需要减少演员数量。
如果你接受这个,那么工作池的任何基本路由器都可以为你工作,有一些上限基于你希望这个参与者在给定时间激活的 cores/threads 数量,即:
http://doc.akka.io/docs/akka/snapshot/scala/routing.html#SmallestMailboxPool
另一种方法可能是创建一个 actor 来处理每个传入的任务,这些任务将在处理输入后终止。为此,您只需在传入消息的处理程序中创建参与者,并让该参与者在完成其工作并提供结果后自行停止。
除了这些策略之外的任何优化都应该在您尝试过这些策略并发现它们不足之后才进行——不要过早地优化。
考虑使用 https://github.com/iheartradio/kanaloa 一组使用 Akka actor 实现的工作调度器,具有自动缩放、背压、断路器和实时监视器。