2014-05-01 53 views
2

我一直在使用Akka创建一个实时处理系统,该系统接收Twitter流(现在)并使用参与者以各种方式处理所述消息。我一直在阅读有关,其他人已经用阿卡和这个特殊的博客帖子内置类似的架构吸引了我的眼球:Akka - 拉模式和持久邮箱

http://blog.goconspire.com/post/64901258135/akka-at-conspire-part-5-the-importance-of-pulling

在这里,他们解释推动工作的时候(即信息)演员VS出现的不同问题让演员拉动工作。为了解释这篇文章,通过推送消息,没有内建的方法可以知道哪个工作单元由哪个工作人员接收,也不能被可靠地跟踪。另外,如果一名员工突然收到大量的消息,其中每条消息都很大,那么您可能会不知所措,并且机器可能会耗尽内存。或者,如果处理是CPU密集型处理,则可能导致节点由于CPU抖动而无响应。此外,如果jvm崩溃,您将丢失演员在其邮箱中的所有消息。

拉动消息很大程度上消除了这些问题。由于特定的演员必须从协调员处获得工作,协调员总是知道每个工作人员的工作单位;如果一名工人死亡,协调员知道要重新处理哪个工作单元。消息也不在工作人员的邮箱中(因为它只是拉动一条消息并在处理另一条消息之前对其进行处理),因此如果参与者崩溃,这些邮箱的丢失不是问题。此外,由于每个员工在完成当前任务后只会请求更多工作,因此不会担心员工接受或启动的工作量多于可同时处理的工作量。显然,这个解决方案也存在问题,例如协调器本身崩溃时会发生什么,但现在让我们假设这是一个非问题。更多关于此拉模式也可以在“让它崩溃”的网站上找到该博客引用:

http://letitcrash.com/post/29044669086/balancing-workload-across-nodes-with-akka-2

这让我想到了一个可能的替代这样拉动模式是做推动,但与持久邮箱。我想到的一个例子是实现一个使用RabbitMQ的邮箱(Redis,MongoDB,Kafka等其他数据存储也可以在这里工作),然后让每个路由器(所有这些都将用于相同目的)共享相同的消息队列(或相同的DB /集合/等...取决于所使用的数据存储)。换句话说,每个路由器在RabbitMQ中都有自己的队列作为邮箱。这样,如果其中一个路由器出现故障,那些仍然处于运行状态的用户可以简单地继续从RabbitMQ中检索,而不用担心队列会因为不再使用典型的内存邮箱而溢出。另外,由于他们的邮箱没有在内存中实现,如果一个routee崩溃了,它可能丢失的大部分信息只会是它在崩溃之前处理的单个邮件。如果整个路由器出现故障,那么您可以期待RabbitMQ(或任何正在使用的数据存储)处理负载增加,直到路由器能够恢复并再次开始处理消息。

就持久邮箱而言,似乎早在2.0版本中,Akka倾向于更积极地支持这些工具,因为他们已经实施了一些可以与MongoDB,ZooKeeper等协同工作的工具。但是,似乎无论出于何种原因他们自从最新版本(本文撰写时的2.3.2)没有提到它们之后就放弃了这个想法。您仍然可以通过实现MessageQueue接口来实现自己的邮箱,该接口为您提供诸如enqueue(),dequeue()等方法......因此,使与RabbitMQ,MongoDB,Redis等协同工作的方法似乎不会成为一个问题。

无论如何,只是想让你的家伙和gals的想法。这似乎是一个可行的替代做拉?

回答

1

这个问题在akka-user上也产生了一个相当长的信息。总之,最好是明确地管理工作项目,由(可执行的)参与者处理,可变数量的工作者参与者可以从中获得新的工作,因为这允许更好的资源管理和显式控制处理的内容以及如何处理重试。