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

Do Spark RDD tuple fields need to be serializable? Mahout Drm seems to say no

Mahout 的 DrmRdd 类型定义为

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

转换为

RDD[(K,Vector)]

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

这让我有些头疼,不知道如何生成 RDD[(K,Vector)] 来包装到 Mahout Drm 中,而不会被 Vector 不可序列化这一事实绊倒。

我的问题是,spark RDD 元组什么时候需要序列化?或者它们是否只需要为某些需要它们通过洗牌传递的函数进行序列化?

好吧,从技术上讲,如果没有理由序列化(没有洗牌、序列化缓存或类似过程,您可以使用 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 tools and Vector is actually registered there:

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

并提供specialized serializer

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