所以,我在Spark中遇到了臭名昭着的Task Not Serializable
错误。这是相关的代码块:
val labeledPoints: RDD[LabeledPoint] = events.map(event => {
var eventsPerEntity = try {
HBaseHelper.scan(...filter entity here...)(sc).map(newEvent => {
Try(new Object(...))
}).filter(_.isSuccess).map(_.get)
} catch {
case e: Exception => {
logger.error(s"Failed to convert event ${event}." +
s"Exception: ${e}.")
throw e
}
}
})
基本上我想要实现的是我正在sc
访问map
这是我的Spark Context对象。在运行时,我收到Task Not Serializable
错误。
这是我能想到的潜在解决方案:
查询没有sc
的HBase,我可以这样做,但反过来我会有一个列表。 (如果我尝试并行化;我必须再次使用sc
。列表会导致我无法使用reduceByKey
,在我的其他问题中建议使用here。所以我也不能成功地实现这一点,因为我不知道如果没有reduceByKey
我将如何实现this。另外我真的想要使用RDD:)
所以我正在寻找另一个解决方案+询问我是否做错了什么。提前谢谢!
更新
基本上,我的问题就是这样:
我有一个名为RDD
的{{1}}。这是整个HBase表。注意:每个events
都由event
执行,performerId
也是event
中的字段,即event.performerId
。
对于event
中的每个events
,我需要计算event.numericColumn
与numericColumn
的{{1}}的平均值之比(event
的子集{1}})由同一events
执行。
我在映射performerId
时尝试这样做。在events
内,我试图根据map
过滤事件。
基本上,我正在尝试将每个performerId
转换为event
,上面的比例将成为我在Vector中的一项功能。即对于每一个事件,我都试图获得
LabeledPoint
我将不胜感激任何帮助。谢谢!
答案 0 :(得分:1)
如果适用,一个选项是加载整个 HBase表(或者 - 如果您有任何隔离方式,可能与events
RDD中的某个事件匹配的所有元素他们没有经过RDD)进入Dataframe,然后使用 join 。
要将HBase表中的数据加载到Dataframe中,您可以使用Hortonworks中的预览Spark-HBase Connector。然后,在两个数据帧之间执行正确的连接操作应该很容易。
答案 1 :(得分:0)
您可以将列表添加为事件的新字段 - 通过获取新RDD(事件+实体列表)。然后,您可以使用常规Spark命令“爆炸”列表,从而获得多个事件+列表项记录(使用DataFrames / DataSet比使用RDD更容易实现此操作)
答案 2 :(得分:-1)
很简单,你不能在RDD Closure上使用spark上下文,所以找到另一种方法来处理它。