火花短路,排序和懒惰地图

问题描述:

我正在处理一个优化问题,该问题涉及在对象集合上最小化昂贵的地图操作。火花短路,排序和懒惰地图

天真溶液会是这样的

rdd.map(expensive).min() 

然而,映射函数将返回保证是值> = 0。因此,如果任何一个的结果是0,I可以采取作为答案和不需要计算其余的地图操作。

是否有使用Spark做到这一点的惯用方式?

是否有一种使用Spark做到这一点的惯用方式?

不。如果你关心像这样的低级优化,那么Spark不是最好的选择。这并不意味着它是完全不可能的。

如果你能举例来说尝试这样的事情:

rdd.cache() 
(min_value,) = rdd.filter(lambda x: x == 0).take(1) or [rdd.min()] 
rdd.unpersist() 

短路分区:

def min_part(xs): 
    min_ = None 
    for x in xs: 
     min_ = min(x, min_) if min_ is not None else x 
     if x == 0: 
      return [0] 
    return [min_] in min_ is not None else [] 

rdd.mapPartitions(min_part).min() 

两者通常将执行超过需要,每一种有稍微不同的性能配置,但可以跳过评估一些记录。对于稀少的零来说,第一个可能会更好。

您甚至可以收听累加器更新并在看到0时使用sc.cancelJobGroup。下面是类似的方法的一个例子Is there a way to stream results to driver without waiting for all partitions to complete execution?

如果“贵”是真的昂贵,也许你可以写的“昂贵”,比方说,SQL的结果(或者提供给所有工人的任何其它存储)。 然后在“昂贵”开始时检查当前存储的编号,如果它为零,则从“昂贵”返回零而不执行昂贵的部分。

您也可以为每位员工做到这一点,这将为您节省大量时间,但不会成为“全球”。