序列化是否会降低Spark性能



给定以下案例类别:

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

从用户实例的List创建RDD

以下代码过滤RDD以删除50岁以上的用户

trait Process {
  def test {
    val rdd = ... // create RDD
    rdd.filter(_.age>50)
  }
}

为了添加日志记录,创建了一个单独的验证函数并将其传递给过滤器,如下所示:

trait Process {
  def validate(user:User) {
    if (user.age>50) {
      true
    }
    else {
      println("FAILED VALIDATION")
      false
    }
  }
  def test {
    val rdd = ... // create RDD
    rdd.filter(validate)
  }
}

引发以下异常:

org.apache.spark.SparkException: Task not serializable

代码的工作原理是使定义验证函数的类可序列化:

trait Process extends Serializable

这是处理Task not serializable异常的正确方法吗?还是在Spark中使用序列化会降低性能?有更好的方法吗?

感谢

在Spark 中使用序列化会降低性能吗

任务序列化(与混洗/收集数据时发生的数据串行化相反)在性能方面很少引人注目,只要序列化的对象很小。每个任务序列化一次(与处理的数据量无关)。

在这种情况下(序列化Process实例),性能影响可能可以忽略不计,因为它是一个小对象。

这种假设("Process很小,所以没关系")的风险在于,随着时间的推移,Process可能会发生变化:开发人员很容易不会注意到这个类被序列化了,所以他们可能会添加一些成员,从而使其变慢。

有没有更好的方法来做这个

通过使用静态方法(objects的方法,而不是类),可以完全避免序列化。在这种情况下,您可以为Process:创建伴随对象

import Process._
trait Process {
  def test {
    val rdd = ... // create RDD
    rdd.filter(validate)
  }
}
object Process {
  def validate(user:User) {
    if (user.age>50) {
      true
    } else {
      println("FAILED VALIDATION")
    false
    }
  }

对象是"静态"的,因此Spark可以在不序列化的情况下使用它们。

最新更新