我有RDD
需要访问其他RDD
的数据。但是,我总是收到Task not Serializable
错误。我扩展了Serializable
类,但它没有用。代码是:
val oldError = rddOfRatings.aggregate(0.0)((accum, rating) =>
accum + calcError(rating.rating,
us.lookup(rating.user)(0),
it.lookup(rating.product)(0)).abs, _+_ ) / rddSize
us
,it
和rddOfRatings
是其他RDD
的地方。我不明白的是,如果RDD
是不可变的,那么为什么不允许我允许我从另一个RDD
内访问RDD
?问题似乎在于us
和it
,因为当我为本地集合删除它时,它可以正常工作。
谢谢。
答案 0 :(得分:2)
答案 1 :(得分:1)
rdd.lookup
1是一项昂贵的操作,即使可能,您也可能不想这样做。
此外,"序列化" RDD没有意义,因为RDD只是对数据的引用,而不是数据本身。
这里采取的方法可能取决于这些数据集的大小。如果us
和it
RDD与rddOfRatings
的大小大致相同(根据预期的查找情况,它看起来是这样的),最好的方法是事先加入这些内容。
//请注意我并不知道您的收藏品的实际结构,因此请将此作为说明性示例
val ratingErrorByUser = us.map(u => (u.id, u.error))
val ratingErrorByProduct = it.map(i=> (i.id, i.error))
val ratingsBykey = rddOfRatings.map(r=> (r.user, (r.product, r.rating)))
val ratingsWithUserError = ratingsByKey.join(ratingErrorByUser)
val ratingsWithProductError = ratingsWithUserError.map{case (userId, ((prodId, rating),userErr))} => (prodId,(rating, userErr))}
val allErrors = ratingsWithProductError.join(ratingErrorByProduct)
val totalErr = allErrors.map{case (prodId,((rating, userErr),prodErr)) => calcError(userErr, math.abs(prodErr), rating)}.reduce(_+_)
val total = totalErr / rddOfRatings.count
可能会轻松得多
1如果必须进行查询(在这种情况下看起来不像!),请查看Spark IndexedRdd