繁体   English   中英

saveAsObjectFile 和persist in apache spark有什么区别?

[英]What is the difference between saveAsObjectFile and persist in apache spark?

我试图比较 java 和 kryo 序列化,并在将 rdd 保存在磁盘上时,它在使用 saveAsObjectFile 时给出相同的大小,但在持久化时它在 spark ui 中显示不同。 Kryo 比 java 小,但具有讽刺意味的是,java 的处理时间比 spark UI 没有预料到的 kryo 的处理时间要短?

val conf = new SparkConf()
    .setAppName("kyroExample")
    .setMaster("local[*]")
    .set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
    .registerKryoClasses(
      Array(classOf[Person],classOf[Array[Person]])
    )

  val sparkContext = new SparkContext(conf)
  val personList: Array[Person] = (1 to 100000).map(value => Person(value + "", value)).toArray

  val rddPerson: RDD[Person] = sparkContext.parallelize(personList)
  val evenAgePerson: RDD[Person] = rddPerson.filter(_.age % 2 == 0)

  case class Person(name: String, age: Int)

  evenAgePerson.saveAsObjectFile("src/main/resources/objectFile")
  evenAgePerson.persist(StorageLevel.MEMORY_ONLY_SER)
  evenAgePerson.count()

persistsaveAsObjectFile解决不同的需求。

persist有一个误导性的名字。 它不应该用于永久保留 rdd 结果。 Persist 用于在 spark workfklow 期间临时持久化 rdd 的计算结果。 用户无法控制持久化数据帧的位置。 Persist 只是使用不同的缓存策略进行缓存 - 内存、磁盘或两者兼而有之。 事实上, cache只会使用默认的缓存策略调用persist化。

例如

val errors = df.filter(col("line").like("%ERROR%"))
// Counts all the errors
errors.count()

// Counts errors mentioning MySQL
// Runs again on the full dataframe of all the lines , repeats the above operation 
errors.filter(col("line").like("%MySQL%")).count()

对比

val errors = df.filter(col("line").like("%ERROR%"))
errors.persist()
// Counts all the errors
errors.count()

// Counts errors mentioning MySQL
// Runs only on the errors tmp result containing only the filtered error lines
errors.filter(col("line").like("%MySQL%")).count()

saveAsObjectFile用于永久持久化。 它用于将 spark 作业的最终结果序列化到持久且通常是分布式的文件系统上,例如hdfsamazon s3

Spark persist 和 saveAsObjectFile 完全不同。

持久 - 将您的 RDD DAG 持久化到请求的 StorageLevel,这意味着从现在开始,应用在此 RDD 上的任何转换都将仅根据持久化的 DAG 进行计算。

saveAsObjectFile - 只需将 RDD 保存到序列化对象的 SequenceFile 中。

saveAsObjectFile 根本不使用“spark.serializer”配置。 你可以看到下面的代码:

  /**
   * Save this RDD as a SequenceFile of serialized objects.
   */
  def saveAsObjectFile(path: String): Unit = withScope {
    this.mapPartitions(iter => iter.grouped(10).map(_.toArray))
      .map(x => (NullWritable.get(), new BytesWritable(Utils.serialize(x))))
      .saveAsSequenceFile(path)
  }

saveAsObjectFile 使用 Utils.serialize 来序列化您的对象,当序列化方法定义为:

  /** Serialize an object using Java serialization */
  def serialize[T](o: T): Array[Byte] = {
    val bos = new ByteArrayOutputStream()
    val oos = new ObjectOutputStream(bos)
    oos.writeObject(o)
    oos.close()
    bos.toByteArray
  }

saveAsObjectFile 始终使用 Java 序列化。

另一方面,persist 会使用你配置他的配置的 spark.serializer。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM