flink中的案例类序列化

时间:2016-03-16 17:23:53

标签: scala serialization apache-flink

我正在尝试使用Scala的case类构建数据集(我想在元组上使用case类,因为我想按名称连接字段)。

以下是我正在进行的联接的一次迭代:

case class TestTarget(tacticId: String, partnerId:Long)

campaignPartners.join(partnerInput).where(1).equalTo("id") {
   (target, partnerInfo, out: Collector[TestTarget]) => {
       partnerInfo.partner_pricing match {
           case Some(pricing) =>
             out.collect(TestTarget(target._1, partnerInfo.partner_id))
           case None => ()
    }
  }
}

显然这会引发错误:

  

org.apache.flink.api.common.InvalidProgramException:任务没有   可序列化的   org.apache.flink.api.scala.ClosureCleaner $ .ensureSerializable(ClosureCleaner.scala:179)     在   org.apache.flink.api.scala.ClosureCleaner $清洁机壳(ClosureCleaner.scala:171)     在org.apache.flink.api.scala.DataSet.clean(DataSet.scala:121)at at   org.apache.flink.api.scala.JoinDataSet $$匿名$ 2(joinDataSet.scala:108)。     在   org.apache.flink.api.scala.JoinDataSet.apply(joinDataSet.scala:107)     在   com.adfin.dataimport.vendors.dbm.Job.calculateVendorFees(Job.scala:84)

我看过文档here,声明我需要为类实现serializable。据我所知,在新版本的Scala中没有很好的方法来自动序列化案例类。 (我查看了手动序列化,但我认为我需要做一些额外的工作,链接才能工作)。

编辑: 根据Till Rohrmann的建议,我试图用小案例重现这个错误。这就是我以前尝试重现错误的方法。此示例有效,我无法重现错误。我也尝试将Option案件放在任何地方,但这会导致作业失败。

val text = env.fromElements("To be, or not to be,--that is the question:--")

val words = text.flatMap { _.toLowerCase.split("\\W+") }.map(x => (1,x))

val nums = env.fromElements(List(1,2,3,4,5)).flatMap(x => x).map(x => First(1,x))



val counts = words.join(nums).where(0).equalTo("a") {
  (a, b, out: Collector[TestTarget]) => {
    b.b match {
      case 2 => ()
      case _ => out.collect(TestTarget(a._2, b.b))
    }
  }
}

1 个答案:

答案 0 :(得分:1)

我的程序的定义使用了一个类

public class Coin {
    String coin;
    int value;

    public Coin(String coinName, int coinValue){
        coin = coinName;
        value = coinValue;
    }

    public String toString(){
        StringBuffer sb = new StringBuffer();
        sb.append("coinName=");
        sb.append(this.coin);
        sb.append(";");
        sb.append("value=");
        sb.append(this.value);
        return sb.toString();
    }
}

因为它是一个内部类,所以它没有被自动序列化

如果你把课程改为不是内部课程,那么一切都会成功

class Job(conf: AdfinConfig)(implicit env: ExecutionEnvironment)
        extends DspJob(conf){
    ...
    case class TestTarget(tacticId: String, partnerId:Long)
    campaignPartners.join(partnerInput).where(1).equalTo("id") {
    ...
}