我正在使用zeppelin来运行流媒体作业。
以下代码会引发以下错误 -
引起:java.io.NotSerializableException:org.apache.spark.streaming.kinesis.KinesisInputDStream的对象可能被序列化,可能是RDD操作关闭的一部分。这是因为正在从闭包内引用DStream对象。请在此DStream中重写RDD操作以避免这种情况。这已被强制执行以避免使用不必要的对象使Spark任务膨胀。 序列化堆栈:
val v = kinesisStream .map(x => { // function defined within map, this one works def transform_iso_timestamp3 (event_type:String,ts:String):String = { event_type match{ case "low_balance" => ts.replace("T","").stripMargin.substring(0,19) case _ => ts.replace("T", " ").stripMargin.substring(0,16)+":00" } } JSON.parseFull(new String(x)) match { case Some(a:Map[String,Any]) => (a("event_type").toString,transform_iso_timestamp2(a("event_type").toString,a("time").toString),1) case _ => ("FAIL","2017-10-10 00:00:00",1)} } ).map(r => Counts(r._1,r._2,r._3))
我在地图闭包之外使用的唯一功能是 transform_iso_timestamp2
它是一个简单的功能。
def transform_iso_timestamp2(event_type:String,ts:String):String = {
event_type match{
case "low_balance" => ts.replace("T", " ").stripMargin.substring(0,19)
case _ => ts.replace("T", " ").stripMargin.substring(0,16)+":00"
}
}
我想明白为什么这不可序列化?它没有提到外部的东西。
请注意,如果我使用地图中定义的 transform_iso_timestamp3 功能,那么它可以正常工作。
如果我创建包含 transform_iso_timestamp2 的简单scala对象,请将其打包到jar中然后将其导入到我的代码中,然后它可以正常工作。
另一种使这项工作的方法是在DStream上使用transform而不是map。我不确定为什么会有效。