我正在以下列方式集成Akka actor和Spark的使用:当一个任务在Spark节点之间分配时,在处理这些任务时,每个节点还会周期性地将度量数据发送到位于其他位置的其他收集器进程。网络通过使用Akka actor(通过akka-remote连接到远程进程)。
基于actor的度量标准发送/接收功能在独立模式下使用时效果很好,但是当集成到Spark任务中时,会引发以下错误:
java.lang.IllegalStateException: Trying to deserialize a serialized ActorRef without an ActorSystem in scope. Use 'akka.serialization.Serialization.currentSystem.withValue(system) { ... }'
at akka.actor.SerializedActorRef.readResolve(ActorRef.scala:407) ~[akka-actor_2.10-2.3.11.jar:na]
如果我理解正确,问题的根源是Spark节点无法反序列化 ActorRef ,因为它没有完成此操作所需的完整信息。我理解将ActorSystem放在范围内会修复它,但我不确定如何使用建议的akka.serialization.Serialization.currentSystem.withValue(system) { ... }
Akka官方文档非常适合他们涵盖的所有主题。不幸的是,专门用于序列化的章节可以改进恕我直言。
注意:有一个类似的SO问题here但是接受的解决方案过于具体,因此在一般情况下并不真正有用
答案 0 :(得分:2)
ActorSystem
负责ActorRef
个对象涉及的所有功能。
当您编写类似
的程序时actorRef ! message
你实际上是在ActorSystem中调用一堆工作,而不是ActorRef,把消息放在正确的邮箱中,开发Actor以在线程池中运行receive方法等等...来自documentation:
actor系统管理它配置为按顺序使用的资源 运行它包含的actor。可能有数百万的演员 在一个这样的系统中,在所有的咒语之后,将它们视为 它们的重量仅为300字节左右 每个实例。当然,消息的确切顺序 在大型系统中处理的应用程序无法控制 作者
这就是为什么你的代码可以很好地“独立”工作,但不能在Spark中工作。您的每个Spark节点都缺少ActorSystem机制,因此即使您可以在节点中反序列化ActorRef,也不会有ActorSystem来处理节点函数中的!
。
您可以在每个节点内建立一个ActorSystem,并使用(i)remoting通过actorSelection
向“master”ActorSystem中的ActorRef发送消息,或者(ii)您提到的序列化方法node的ActorSystem将是你引用的例子中的system
。