繁体   English   中英

Apache Spark mapPartition奇怪的行为(懒惰的评估?)

[英]Apache Spark mapPartition strange behavior (lazy evaluation?)

我正在尝试使用以下代码(在Scala中)在RDD上记录每个mapPartition操作的执行时间:

rdd.mapPartitions{partition =>
   val startTime = Calendar.getInstance().getTimeInMillis
   result = partition.map{element =>
      [...]
   }
   val endTime = Calendar.getInstance().getTimeInMillis
   logger.info("Partition time "+(startTime-endTime)+ "ms")
   result
}

问题在于它在开始执行映射操作之前立即记录了“分区时间”,因此我总是获得2毫秒左右的时间。

我通过观察Spark Web UI注意到了这一点,在日志文件中,有关执行时间的行在任务开始后立即出现,而不是在预期的末尾出现。

有人可以解释我为什么? 在mapPartitions内部,代码应线性执行,否则我错了吗?

谢谢

问候卢卡

partitions内部的mapPartitions是一个Iterator[Row] ,以及Iterator被Scala中(即,当迭代器被消耗)懒惰地评估。 这与Spark的懒惰评估无关!

调用partitions.size将触发对映射的评估,但将消耗Iterator(因为它只能迭代一次)。 一个例子

val it = Iterator(1,2,3)
it.size // 3
it.isEmpty // true

您可以做的是将Iterator转换为非惰性集合类型:

rdd.mapPartitions{partition =>
   val startTime = Calendar.getInstance().getTimeInMillis
   result = partition.map{element =>
      [...]
   }.toVector // now the statements are evaluated
   val endTime = Calendar.getInstance().getTimeInMillis
   logger.info("Partition time "+(startTime-endTime)+ "ms")
   result.toIterator
}

编辑:请注意,您可以使用System.currentTimeMillis() (甚至System.nanoTime() )来代替Calendar

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM