java - registrationrequired - spark dra



Spark-任务不可序列化:如何使用调用外部类/对象的复杂地图封闭? (2)

看看这个问题: Scala + Spark - 任务不可序列化:java.io.NotSerializableExceptionon。 当仅在类而不是对象上调用函数外的函数时

问题:

假设我的映射器可以是内部调用其他类的函数(def),并创建对象并在里面做不同的事情。 (或者它们甚至可以是扩展(Foo)=> Bar的类,并在其应用方法中执行处理 - 但是现在让我们忽略这种情况)

Spark仅支持闭包的Java序列化。 有没有办法呢? 我们可以用东西而不是封闭来做我想做的事吗? 我们可以很容易地用Hadoop来做这种事情。 这件事情让Spark几乎无法使用。 一个不能期望所有的第三方库有所有类扩展Serializable!

可能的解决方案:

像这样的东西似乎是有用的: https//github.com/amplab/shark/blob/master/src/main/scala/shark/execution/serialization/KryoSerializationWrapper.scala

它似乎是一个包装是答案,但我不能看到如何。

https://ffff65535.com


我想出了如何自己做这个!

你只需要在通过闭包之前序列化对象,然后反序列化。 即使你的类不是可序列化的,这种方法也是可行的,因为它在幕后使用了Kryo。 所有你需要的是一些咖喱。 ;)

以下是我如何做的一个例子:

def genMapper(kryoWrapper: KryoSerializationWrapper[(Foo => Bar)])
               (foo: Foo) : Bar = {
    kryoWrapper.value.apply(foo)
}
val mapper = genMapper(KryoSerializationWrapper(new Blah(abc))) _
rdd.flatMap(mapper).collectAsMap()

object Blah(abc: ABC) extends (Foo => Bar) {
    def apply(foo: Foo) : Bar = { //This is the real function }
}

随意让Blah像你想要的那样复杂,类,伴侣对象,嵌套类,对多个第三方库的引用。

KryoSerializationWrapper参照: https//github.com/amplab/shark/blob/master/src/main/scala/shark/execution/serialization/KryoSerializationWrapper.scala


在使用Java API的情况下,您应该在传递给映射函数闭包时避免使用匿名类。 而不是做地图(新功能),你需要一个扩展你的功能,并将其传递给地图(..)的类请参阅: https//yanago.wordpress.com/2015/03/21/apache-spark/





apache-spark