有没有办法在Spark中“中断” reduce操作?
假设我要这样做:
var result: Int = 0
while (iterator.hasNext()) {
if (/*Some condition on result*/) {
result = someFunction(result, iterator.next())
} else {
break
}
}
在Spark中执行此操作的方法是reduce
的RDD(包含迭代器返回的内容):
rdd.reduce((result, next) =>
if (/*Some condition on result*/) someFunction(result, next)
else result
)
但是如果计算条件很昂贵怎么办?我可以这样做:
//result is now of type (Int, Boolean) and the initial Boolean is true
rdd.reduce((result, next) =>
if (result._2 && /*Some condition on result*/) (someFunction(result._1, next._1), true)
else (result._1, false)
)
有没有更清洁的方法?
答案 0 :(得分:1)
不幸的是,您想要执行的操作不一定适合spark的计算模型。由于数据是跨分区划分的,因此不一定有明确定义的顺序。如果您不使用spark,则适当的函数调用应为takeWhile
。
val data: List[DType] = ...
...
data.takeWhile(condition).map(someFunction)
您几乎可以通过mapPartitions获得此功能。这会将功能应用于每个分区上的迭代器。
val data: RDD[DType] = ...
...
data.mapPartitions(partitionData: Iterator[DType] => partitionData.takeWhile(condition).map(someFunction))