将简单功能移出UDF时,任务无法序列化

时间:2018-11-27 16:59:23

标签: scala apache-spark

我试图分离UDF中的功能以编写测试,但是这会导致序列化类型错误?我尝试了创建UDF的其他格式,但仍然无法正常工作。

为什么这样做?

   protected val normalizeDomain = udf {(dealer_url: String) => 
     var domain = if (dealer_url.startsWith("http://") || dealer_url.startsWith("https://")) dealer_url else s"http://$dealer_url"
     domain = new URL(domain).getHost
     if (domain.startsWith("www.")) domain.replace("www.", "") else domain
   }

但是不是吗?

  def normalizeDomainDef(dealer_url: String):String = {
    var domain = if (dealer_url.startsWith("http://") || dealer_url.startsWith("https://")) dealer_url else s"http://$dealer_url"
    domain = new URL(domain).getHost
    if (domain.startsWith("www.")) domain.replace("www.", "") else domain
  }
  val normalizeDomain = udf[String, String](normalizeDomainDef)

执行后者时,我得到:

Caused by: java.io.NotSerializableException: line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$
Serialization stack:
    - object not serializable (class: line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$, value: line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$@131552b)
    - field (class: line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$$anonfun$3, name: $outer, type: class line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$)
    - object (class line9e1150bafcc941e3b83a5f4ad173d2ae122.$read$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$$iw$DealerVDPUrlMaker$$anonfun$3, <function1>)
    - element of array (index: 4)
    - array (class [Ljava.lang.Object;, size 5)
    - field (class: org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$10, name: references$1, type: class [Ljava.lang.Object;)

1 个答案:

答案 0 :(得分:0)

最可能的问题在于您的normalizeDomainDef所在的事实。当您使用def时,这意味着您将其放入某个类中,现在该类的整个实例都应序列化为调用该方法,可能  该类包含许多不可序列化的内容。要对其进行修复,请尝试将函数放入这样的独立顶级object中:

// top level object
object MyUdfs {
  def normalizeDomainDef(dealer_url: String):String = {
    var domain = if (dealer_url.startsWith("http://") || dealer_url.startsWith("https://")) dealer_url else s"http://$dealer_url"
    domain = new URL(domain).getHost
    if (domain.startsWith("www.")) domain.replace("www.", "") else domain
  }

  val normalizeDomain = udf[String, String](normalizeDomainDef)
}