我正在尝试在Akka之上实现MapReduce,很幸运能找到本书的代码Akka Essentials。但是,我发现这个示例实现有两个主要问题,两者看起来都像基本的并发设计缺陷,在一本关于Akka的书中找到它是非常令人震惊的:
完成后,客户端将调用shutdown()
,但此时无法保证消息通过WCMapReduceServer。我看到WCMapReduceServer在任何时候只获取部分数量的客户端消息,然后WCMapReduceServer输出[INFO] [06/25/2013 09:30:01.594] [WCMapReduceApp-5] [ActorSystem(WCMapReduceApp)] REMOTE: RemoteClientShutdown@akka://ClientApplication@192.168.224.65:2552
,意味着客户端shutdown()
在客户端实际设法刷新所有未决消息之前发生。在客户端代码line 41中,我们看到shutdown()
发生时没有先刷新。在关闭系统之前,Akka是否有办法强制执行刷新出站邮件?
另一个实际上更大的缺陷,我已经修复了,是用于向MapReduce服务器发出EOF信号的方式,主要任务(文字文件)完成后给定所有子任务(文件的每一行)完成。他发送一个特殊的字符串消息DISPLAY_LIST
,此消息排队的优先级最低see code。这里的一个重大缺陷是即使DISPLAY_LIST
具有最低优先级,如果任何Map(或Reduce)任务任意长,DISPLAY_LIST
消息将在所有MapReduce子任务完成之前通过,因此此MapReduce示例的结果是非确定性的,即您可以在每次运行中获得不同的字典。可以通过用以下内容替换MapActor#onReceive implementation来揭示问题,即将一个Map步骤任意长一点:
public void onReceive(Object message) {
System.out.println("MapActor -> onReceive(" + message + ")");
if (message instanceof String) {
String work = (String) message;
// ******** BEGIN SLOW DOWN ONE MAP REQUEST
if ("Thieves! thieves!".equals(work)) {
try {
System.out.println("*** sleeping!");
Thread.sleep(5000);
System.out.println("*** back!");
}
catch (InterruptedException e) {
e.printStackTrace();
}
}
// ******** END SLOW DOWN ONE MAP REQUEST
// perform the work
List<Result> list = evaluateExpression(work);
// reply with the result
actor.tell(list);
} else throw new IllegalArgumentException("Unknown message [" + message + "]");
}
进一步阅读这本书后发现:
我们有Thread.sleep(),因为无法保证订单的顺序 消息被处理。第一个Thread.sleep()方法 确保 以前完全处理所有字符串句子消息 我们发送结果消息。
我很抱歉,Thread.sleep()
从未成为确保并发性的方法。因此,难怪这样的书会在他们的例子中充满基本的并发缺陷。
答案 0 :(得分:1)
我已经解决了这两个问题,并且还将代码迁移到最新的Akka 2.2-M3版本。
第一个问题的解决方案是让MapReduce远程MasterActor在收到所有消息发送后从客户端发送的TaskInfo通知后立即发回ShutdownInfo通知。 TaskInfo包含MapReduce任务具有多少子任务的信息,例如:在这种情况下,文本文件中有多少行。
第二个问题的解决方案是发送具有子任务总数的TaskInfo。在这里,AggregatorActor计算它已经处理的子任务的数量,将它与TaskInfo进行比较,并表示作业在匹配时完成(当前只是打印一条消息)。
输出中显示了有趣且正确的行为:
system.shutdown()
并终止客户端。请注意,MapReduce仍处于处理过程中,客户端关闭不会干扰。可以从我的存储库中获取代码: https://github.com/bravegag/akka-mapreduce-example
随时欢迎反馈。