我通过以下方式集成了 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 但公认的解决方案太具体,因此在一般情况下并没有真正有用

最佳答案

ActorSystem 负责与 ActorRef 对象相关的所有功能。

当你编程时

actorRef ! message

您实际上是在 ActorSystem 中调用大量工作,而不是 ActorRef,将消息放入正确的邮箱中,将 Actor 设置为在线程池中运行接收方法等......来自 documentation :



这就是为什么您的代码“独立”运行良好,但在 Spark 中不能正常运行的原因。每个 Spark 节点都缺少 ActorSystem 机制,因此即使您可以反序列化节点中的 ActorRef,也不会有 ActorSystem 来处理节点函数中的 !

您可以在每个节点内建立一个 ActorSystem 并使用 (i) remoting 通过 actorSelection 或 (ii) 您提到的序列化方法将消息发送到“主”ActorSystem 中的 ActorRef,其中每个节点的 ActorSystem 将是您引用的示例中的 system .

关于scala - Akka : "Trying to deserialize a serialized ActorRef without an ActorSystem in scope"错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33765150/

10-10 14:54