Apache spark 在超时时退出慢速火花贴图,但保留到目前为止的结果
我正在映射一个Spark RDD,它有一个非常昂贵的函数(每行可能需要几十秒) 这项工作可能会花费太长时间,我需要中止它,以便为数据流中的其他工作让路 然而,到目前为止计算的结果对我仍然有用,所以我不想放弃它们,特别是因为它们可能已经花了数小时来计算Apache spark 在超时时退出慢速火花贴图,但保留到目前为止的结果,apache-spark,Apache Spark,我正在映射一个Spark RDD,它有一个非常昂贵的函数(每行可能需要几十秒) 这项工作可能会花费太长时间,我需要中止它,以便为数据流中的其他工作让路 然而,到目前为止计算的结果对我仍然有用,所以我不想放弃它们,特别是因为它们可能已经花了数小时来计算 是否有一种方法可以在超时时提前退出转换,但保留到目前为止计算的部分结果?至少有两种方法可以做到这一点,即从map切换到相关转换: 映射分区 mapPartitions允许我们访问每个分区上的迭代器,因此,如果超时已过期,我们可以简单地假设其中没有项
是否有一种方法可以在超时时提前退出转换,但保留到目前为止计算的部分结果?至少有两种方法可以做到这一点,即从
map
切换到相关转换:
映射分区
mapPartitions
允许我们访问每个分区上的迭代器,因此,如果超时已过期,我们可以简单地假设其中没有项目:
val data = sc.parallelize(1 to 100)
val timeout = 10000
val start = System.currentTimeMillis
data.repartition(10).mapPartitions { iter =>
if (System.currentTimeMillis - start > timeout) Iterator.empty
else iter.map(x => { Thread.sleep(500); x + 1 })
}.count
根据您的环境,您可能需要调整此spark shell示例中的超时,但它应该会产生不同数量的结果,具体取决于您运行相对于设置start
的转换的时间
请注意,分区的数量必须明显高于executor核心的总数,否则所有分区都将立即启动,并且没有什么可以跳过的。因此,在本例中,我们在启动mapPartitions
之前显式地重新划分数据。您可能需要也可能不需要这样做,这取决于数据的大小和配置的核心数
flatMap
更细粒度的方法是使用flatMap
,它允许我们通过返回选项的函数有条件地处理或跳过每一行(如果超时已过期,只返回None
)
这种方法不需要分区,但即使在超时后也会扫描所有剩余的分区(但不会对任何行执行昂贵的处理)。与相关(但不相同)。
// setup as before
data.flatMap{ x => if (System.currentTimeMillis - start > timeout) None
else Some({Thread.sleep(500); x + 1}) }.count