Spark RDD元组字段是否需要可序列化? Mahout Drm似乎说不

时间:2016-07-29 05:04:44

标签: scala apache-spark mahout rdd

Mahout的DrmRdd类型定义为

type DrmRdd[K] = RDD[DrmTuple[K]]

转换为

RDD[(K,Vector)]

但是,Mahout文档明确指出Vector类不可序列化。

这引导我一些关于如何生成RDD [(K,Vector)]以包装到Mahout Drm而不会绊倒Vector不可序列化的事情。

我的问题是,什么时候火花RDD元组需要序列化?或者它们是否只需要对某些要求它们通过shuffle传递的函数进行序列化?

1 个答案:

答案 0 :(得分:3)

从技术上讲,如果没有理由进行序列化(没有随机播放,使用序列化或类似过程进行缓存,您可以使用不可序列化的数据进行RDD。例如,如果您有这样的数据:

class Foo(x: Int)

val rdd = sc.parallelize(1 to 4, 4).map(i => (i, new Foo(i)))

其中Foo不可序列化,您可以计算:

rdd.count
// 4

但你不能distinct.count

rdd.distinct.count
// java.io.NotSerializableException: $line30.$read$$iwC$$iwC$Foo
// Serialization stack:
//  - object not serializable (class: $line30.$read$$iwC$$iwC$Foo, value: ...
//  - field (class: scala.Tuple2, name: _2, type: class java.lang.Object)
//  - object (class scala.Tuple2, (1,$line30.$read$$iwC$$iwC$Foo@70accf6))
//  at ...

因此,非序列化对象仅对仅限于单个任务的临时存储有用。

但Mahout Vector的情况并非如此。 Mahout Spark绑定实际上提供了Kryo registration toolsVector is actually registered there

kryo.addDefaultSerializer(classOf[Vector], new VectorKryoSerializer())

并提供specialized serializer

另请注意,Kryo可以更宽容,因此当您将spark.serializer设置为org.apache.spark.serializer.KryoSerializer distinct.count上面提供的示例即使Foo不可序列化也能正常工作使用Java序列化。