在计算RDD时出现火花,我想知道例如我是否有RDD [Either [A,B]]并想获得RDD [A]和RDD [B],基本上我发现了2种方法:
map
+ filter
val rddA = rddEither.filter(_.isLeft).map(case Left(a) => a)
val rddB = rddEither.filter(_.isRight).map(case Right(b) => b)
flatMap
val rddA = rddEither.flatMap { case Left(a) => Some(a) }
val rddB = rddEither.flatMap { case Right(b) => Some(b) }
如果flatMap更有效?因为可能需要更少的计算量?
还有另一个问题-持久保留RDD来加快执行速度是件好事吗,我的意思是rddEither,因为我将从该源开始计算2个操作,否则Spark会解决这个问题?
答案 0 :(得分:0)
可能collect
会更清晰一些。 (也许会减少计算量,但我认为这不会对性能产生很大影响)。
val rddA = rddEither.collect { case Left(a) => a }
val rddB = rddEither.collect { case Right(b) => b }
“还有另一个问题:坚持rdd来加快执行速度是件好事,我的意思是rddEither,因为我将从该源开始计算2次操作,否则spark会解决这个问题?”
Spark不会解决这个问题,spark是Lazy,这意味着对于每个操作,它将重新计算获得结果所需的所有内容-除非某个地方有缓存。
但是,添加高速缓存并不一定会提高性能,因为如果您希望它快一些,则只需要将其保留在内存中即可,因为这会减少内存,这会损害其他操作的性能。而且,如果将其保存在磁盘中以减少内存使用量,则从磁盘读取反序列化数据所花费的时间可能与重新计算原始 RDD 的时间相同或更长。因此,您可能需要对多个选项进行基准测试以确定哪个更好。
注意:this是有关Spark中内存管理的精彩文章,可能值得一读以优化缓存。