scala - Akka Actors 应该做真正的处理任务吗?

标签 scala concurrency akka actor typesafe

我正在编写一个读取相对较大的文本文件、验证和转换数据的应用程序(文本文件中的每一行都是一个自己的项目,大约有 100M 个项目/文件)并创建某种输出。已经存在一个多线程 Java 应用程序(在读取/处理/持久化任务之间使用 BlockingQueue),但我想实现一个执行相同操作的 Scala 应用程序。

Akka 似乎是构建并发应用程序的一个非常流行的选择。不幸的是,由于 Actor 的异步性质,我仍然不明白单个 Actor 可以或不能做什么,例如如果我可以将 Actor 用作进行某种计算的传统 worker 。

一些文件说 Actor 不应该阻塞,我明白为什么。但是给定的阻塞代码示例总是只提到诸如阻塞文件/网络 IO 之类的事情。这些事情会使参与者等待很短的时间,这当然是一件坏事。

但是如果 Actor “阻止”是因为它实际上做了一些有用的事情而不是等待呢?就我而言,单行/文本项的处理和转换需要 80 毫秒,这是相当长的时间(纯处理,不涉及 IO)。这项工作可以由 Actor 直接完成,还是我应该使用 Future 代替(但是,如果无论如何我都必须使用 Futures,为什么首先使用 Akka ..)?

Akka 文档和示例表明, Actor 可以直接完成工作。但似乎作者只做了非常简单的工作(例如在字符串上调用过滤器或递增计数器,仅此而已)。我不知道他们这样做是为了保持文档简单明了,还是因为你真的不应该在 Actor 内部做更多的事情。

您将如何为我的用例设计一个基于 Akka 的应用程序(读取文本文件,处理需要相当长的每一行,最终持久化结果)?或者这是某种不适合 Akka 的问题?

最佳答案

这完全取决于 Actor 的类型。

我使用这个经验法则:如果你不需要和这个 Actor 交谈并且这个 Actor 没有任何其他职责,那么阻止它做实际工作是可以的。您可以将其视为 Future这就是我所说的“ worker ”。

如果你阻塞一个不是叶子节点(worker)的actor,即工作分配器,那么整个系统将变慢。

有一些模式涉及工作拉/推或每个请求模型的参与者。其中任何一个都可能适合您的应用程序。您可以有一个经理为每件工作创建一个 Actor ,当工作完成时, Actor 将结果发送回经理并死亡。你也可以让一个 Actor 活着,并要求那个 Actor 做更多的工作。您还可以结合 Actor 和 future 。

如果您的处理更复杂并且涉及多个阶段,有时您希望能够与工作人员交谈。在这种情况下, worker 可以将工作委托(delegate)给另一个 Actor 或 future 。

总而言之,不要阻止经理/工作分配参与者。如果这不会减慢您的系统速度,则可以阻止工作人员。

免责声明:阻塞是指做实际工作,而不仅仅是忙于等待,这是永远不会好的。

关于scala - Akka Actors 应该做真正的处理任务吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32561576/

相关文章:

scala - MergeLatest 的默认值

generics - Scala:抽象类型与泛型

Java 执行器 : wait for task termination.

C++11 std::condition_variable:我们可以将锁直接传递给通知线程吗?

scala - Akka:向持久邮箱添加延迟

java - Akka:获取 Actor 总数

scala - 在 Spark 中获取 DataFrame 列的值

scala - sbt 编译导致 stackoverflow 错误

class - 为什么我可以将方法标记为隐式而不是构造函数?

c# - 使用Lock来停止并发执行不起作用?