首页 > 解决方案 > Spark - Kryo 与 JavaSerialization。一样大吗?

问题描述

我在 Spark 中使用缓存。现在,我使用了几个缓存,其中一些在内存中约为 20gb。我首先尝试了 cache() ,后来又尝试了 persist 和 MEMORY_SER ,而且大小很大,所以我改用 java 序列化,其中一些得到了大约 20gb。现在,我想使用 Kryo,我已经注册了类并且我没有收到任何错误,但是它的大小与我在大多数缓存中使用 Kryo 执行它时的大小相同。

我要缓存的一些对象如下:

case class ObjectToCache(id: Option[Long],
                      listObject1: Iterable[ObjectEnriched],
                       mp1: Map[String, ObjectEnriched2],
                       mp2: Map[String, ObjectEnriched3],
                       mp3: Map[String, ObjectEnriched4])

我在 Kryo 注册为:

kryo.register(classOf[Iterable[ObjectEnriched2]])
kryo.register(classOf[Map[String,ObjectEnriched3]])
kryo.register(classOf[Map[String,ObjectEnriched4]])
kryo.register(ObjectEnriched)
kryo.register(ObjectEnriche2)
kryo.register(ObjectEnriched3)
kryo.register(ObjectEnriched4)

难道我做错了什么?有什么方法可以知道它是否使用 Kryo?我认为它正在使用,因为在某些时候我遇到了一个错误,因为我没有剩余空间:

Serialization trace:
mp1 (ObjectEnriched)
        at com.esotericsoftware.kryo.io.Output.flush(Output.java:183)
        at com.twitter.chill.Tuple2Serializer.write(TupleSerializers.scala:37)
        at com.twitter.chill.Tuple2Serializer.write(TupleSerializers.scala:33)

我将 RDD 与 Spark Streaming 一起使用。

标签: apache-sparkkryo

解决方案


难道我做错了什么?有什么方法可以知道它是否使用 Kryo?

您确实在使用 kryo,它正在正确序列化您的对象。

如果设置标志:

conf.set("spark.serializer","org.apache.spark.serializer.KryoSerializer") 
conf.set("spark.kryo.registrator","com.orange.iris.common.serializer.CustomKryoRegistrator")

那么它肯定会使用 Kryo 序列化器。此外,由于您包含标志:

conf.set("spark.kryo.registrationRequired", "true") 

如果它尝试序列化未注册的类,它将失败(有关更多信息,请参阅此答案)。

你有多少内存?如果您使用 Java 和 Kryo 序列化的大小大致相同,并且您坚持使用 MEMORY_ONLY_SER,那么即使使用 Kryo 和 Spark 正在重新计算不适合的部分,您的分区仍然可能不适合内存. 这将导致大小相同。

找出这个问题的几种方法是运行作业并坚持到 MEMORY_AND_DISK_SER,然后在使用 Kryo 时检查磁盘溢出。有关存储级别的更多信息,请参见此处


推荐阅读