请注意:我是一名Java开发人员,不熟悉Scala(遗憾的是)。我会问答案中提供的任何代码示例都将使用Akka的Java API。
我是Akka和演员的新品牌,我正试图建立一个相当简单的演员系统:
因此,一个DataSplitter
actor运行并将相当大的二进制数据块(例如20GB)拆分为100 KB块。对于每个块,数据通过DataCache
存储在DataCacher
中。在后台,DataCacheCleaner
通过缓存搜索并找到可以安全删除的数据块。这就是我们阻止缓存大小变为20GB的方法。
将块发送到DataCacher
进行缓存后,DataSplitter
会通知ProcessorPool
现在需要处理的块。 ProcessorPool
是一个路由器/池,由数万的不同ProcessorActors
组成。当每个ProcessActor
收到通知"进程"一个100KB的数据块然后从DataCacher
获取数据并对其进行一些处理。
如果您想知道为什么我在这里缓解任何问题(因此DataCacher
,DataCache
和DataCacheCleaner
),我的思考是100KB仍然是一个相当大的消息传递给成千上万的actor实例(100KB * 1,000 = 100MB),所以我试图只存储一次100KB的块(在缓存中),然后让每个actor访问它通过缓存API引用。
还有一个Mailman
演员订阅了活动总线并拦截了所有DeadLetters
。
所以,共有6位演员:
DataSplitter
DataCacher
DataCacheCleaner
ProcessorPool
ProcessorActor
Mailman
Akka文档宣称你应该根据子任务而不是纯粹按功能来分解你的演员系统,但我并不完全看到这在这里是如何适用的。手头的问题是我试图在这些演员之间组织一个主管层级,而我不确定最佳/正确的方法是什么。显然ProcessorPool
是一个需要成为ProcessorActors
的父/主管的路由器,所以我们有这个已知的层次结构:
/user/processorPool/
processorActors
但除了已知/明显的关系之外,我不确定如何组织其余的演员。我可以让他们所有人#34;同行"在一位共同/主要演员的指导下:
/user/master/
dataSplitter/
dataCacher/
dataCacheCleaner/
processorPool/
processorActors/
mailman/
或者我可以省略master
(root)actor并尝试在缓存周围使事情更加垂直:
/user/
dataSplitter/
cacheSupervisor/
dataCacher/
dataCacheCleaner/
processorPool/
processorActors/
mailman/
对阿卡来说是个新人我不知道最好的行动方案是什么,如果有人可以帮助我在这里进行一些初步的手持操作,我确定灯泡会全部打开。而且,与组织此层次结构同样重要的是,我甚至不确定我可以使用什么API构造来实际在代码中创建层次结构。
答案 0 :(得分:0)
在一个master
下组织它们会使管理变得更容易,因为您可以通过主管(在这种情况下watched
)访问所有参与者master
。
一个分层实现可以是:
硕士生导师
class MasterSupervisor extends UntypedActor {
private static SupervisorStrategy strategy = new AllForOneStrategy(2,
Duration.create(5, TimeUnit.MINUTES),
new Function<Throwable, Directive>() {
@Override
public Directive apply(Throwable t) {
if (t instanceof SQLException) {
log.error("Error: SQLException")
return restart()
} else if (t instanceof IllegalArgumentException) {
log.error("Error: IllegalArgumentException")
return stop()
} else {
log.error("Error: GeneralException")
return stop()
}
}
});
@Override
public SupervisorStrategy supervisorStrategy() { return strategy }
@Override
void onReceive(Object message) throws Exception {
if (message.equals("SPLIT")) {
// CREATE A CHILD OF MyOtherSupervisor
if (!dataSplitter) {
dataSplitter = context().actorOf(FromConfig.getInstance().props(Props.create(DataSplitter.class)), "DataSplitter")
// WATCH THE CHILD
context().watch(dataSplitter)
log.info("${self().path()} has created, watching and sent JobId = ${message} message to DataSplitter")
}
// do something with message such as Forward
dataSplitter.forward(message, context())
}
}
DataSplitter Actor
class DataSplitter extends UntypedActor {
// Inject a Service to do the main operation
DataSplitterService dataSplitterService
@Override
void onReceive(Object message) throws Exception {
if (message.equals("SPLIT")) {
log.info("${self().path()} recieved message: ${message} from ${sender()}")
// do something with message such as Forward
dataSplitterService.splitData()
}
}
}