使用Joda Time with Spark时,下面的代码会导致java.lang.NullPointerException
val todayBroadcast = sc.broadcast(new DateTime())
val dataRDD2 = dataRDD.filter(item => {
todayBroadcast.value.minusMonths(1).isBefore(item._1)
})
另一方面,下面的代码没有问题
val dataRDD2 = dataRDD.filter(item => {
val today = new DateTime()
today.minusMonths(1).isBefore(item._1)
})
答案 0 :(得分:4)
据我所知,Joda在Apache Spark提供的默认序列化方面存在一些问题。特别是问题在于Kryo序列化器。
您可以查看this SO帖子。
无论如何,尝试禁用Kryo序列化并使用标准Java序列化程序org.apache.spark.serializer.JavaSerializer
。您可以在Spark安装的spark.serializer
内找到属性spark-defaults.conf
。
现在,您应该拥有以下属性:
spark.serializer=org.apache.spark.serializer.KryoSerializer
你必须改为
spark.serializer=org.apache.spark.serializer.JavaSerializer
然后,重新启动Spark安装。如果您正在使用某个特定的发行版(即Cloudera),请使用他们为您提供的管理控制台更改上述属性。
如果您无法使用标准序列化程序,则可以使用其他一些序列化友好格式转换DateTime
,例如String
或Long
(以毫秒为单位)< / p>
告诉我们。
答案 1 :(得分:4)
如果你想继续使用jry日期时间的Kryo序列化,你可以这样做。这使用了https://github.com/magro/kryo-serializers
中已创建的序列化程序创建一个扩展KryoRegistrator
的类import com.esotericsoftware.kryo.Kryo
import org.apache.spark.serializer.KryoRegistrator
class MyRegistrator extends KryoRegistrator {
import de.javakaffee.kryoserializers.jodatime.{JodaDateTimeSerializer, JodaLocalDateSerializer, JodaLocalDateTimeSerializer}
import org.joda.time.{DateTime, LocalDate, LocalDateTime}
override def registerClasses(kryo: Kryo) {
kryo.register(classOf[DateTime], new JodaDateTimeSerializer())
kryo.register(classOf[LocalDate], new JodaLocalDateSerializer())
kryo.register(classOf[LocalDateTime], new JodaLocalDateTimeSerializer())
}
}
然后使用sparkconf
注册该类set("spark.kryo.registrator", "MyRegistrator")
这将序列化joda日期时间,本地日期正确
查看https://spark.apache.org/docs/0.6.1/tuning.html处的文档 - &gt;数据序列化