并发性,如何创建高效的参与者设置?

Concurrency, how to create an efficient actor setup?

好吧,我以前从来没有做过这样密集的并发操作,这个算法主要分为三个部分。

这一切都始于一个包含大约 100 万个项目的向量。 每个项目都分 3 个主要阶段进行处理。

任务 1:发出 HTTP 请求,将接收到的数据转换为包含大约 50 个条目的映射。 任务 2:接收地图并根据在地图中找到的信息进行一些计算以生成 class 实例。 任务 3:接收 class 和 generate/add 到多个输出文件。

我最初是从并发 运行 任务 1 开始的,任务 1 在 64 个线程中有 64K 个条目(每个线程 1024 个条目)。在 for 循环中生成线程。

这很好用并且速度相对较快,但我一直听说 actors 以及它们如何比基本 Java threads/Thread 池更好。我已经创建了一些演员等。但不知道从这里去哪里。

基本上: 1. Actor 是实现这组特定任务的快速并发的正确方法吗?或者我应该采用另一种方法来解决它。 2. 你怎么知道有多少 threads/actors 太多了,特别是在任务一中,你怎么知道同时连接数的限制是多少(我在 mac 上)。是否有一条黄金大道可循?每个线程池有多少个线程与多少个线程?演员等价物? 3. 是否有任何我可以查看的代码以类似的方式实现演员?我看到的所有代码要么是让演员打印 hello world,要么是超级复杂的东西。

1) Actor 是设计组件之间复杂交互的不错选择,因为它们非常类似于 "real life"。您可以将它们视为不同的人互相发送请求,对交互进行建模是很自然的。但是,当您想管理应用程序中不断变化的状态时,它们是最强大的,而您似乎并非如此。您可以在没有参与者的情况下实现快速并发。由你决定。

2) 如果 none 的操作被阻塞,最好的规则是线程数量 = CPU 数量。如果您在编写输出文件时使用非阻塞 HTTP 客户端和 NIO,那么您应该在 IOs 上完全非阻塞,并且可以安全地将应用程序的线程数设置为 CPU 计数你的机器。

3) http://akka.io 上的文档非常非常好和全面。如果你不知道如何使用演员模型,我建议你买一本书——不一定是关于 Akka 的。

如果您真的没有 Akka 经验,请尝试从一些简单的事情开始,例如对您的代码进行一对一的 actor-thread 重写。这将更容易掌握 akka 的工作原理。

在开始时旋转两个 actor,一个用于接收请求,一个用于写入输出文件。然后,当收到请求时,在请求接收者角色中创建一个角色,该角色将进行计算并将结果发送给编写角色。

1) 听起来您的大部分步骤都不是有状态的,在这种情况下,演员会增加复杂性而没有实际好处。如果您需要以可变方式协调多个任务(例如,用于生成输出文件),那么 actor 非常适合该部分。但是 HTTP 获取可能只是调用一些非阻塞 HTTP 库(例如 spray-client - 实际上会使用 actor "under the hood",但不会以一种不会向您公开状态的方式)。

2) 对于阻塞线程,您几乎必须进行试验,看看在不消耗太多资源的情况下您可以 运行 多少。担心远程系统可以处理多少个同时连接,而不是在您自己的机器上达到任何 "connection limits"(您可能会达到文件描述符限制,但如果是这样,最好的做法是增加它)。一旦你弄清楚了这一点,拥有比你想要建立的同时连接数更多的线程没有任何价值。

正如其他人所说,对于非阻塞的一切,您应该只拥有与 CPU 核心数量相似的线程数量(我还听说过“2x CPUs + 1",因为这样可以确保每当 CPU 空闲时始终有一个线程可用。

对于演员,我不担心演员太多。它们非常轻便。