我有一种情况,当给定批次处理时,底层函数的运行效率会明显提高。我有这样的代码:
// subjects: RDD[Subject]
val subjects = Subject.load(job, sparkContext, config)
val classifications = subjects.flatMap(subject => classify(subject)).reduceByKey(_ + _)
classifications.saveAsTextFile(config.output)
classify
方法适用于单个元素,但对元素组的操作效率更高。我考虑使用coalesce
将RDD拆分为块并作为一个组对每个块进行操作,但是这有两个问题:
classify
事先并不知道群组应该有多大,而且根据输入的内容而有所不同。关于如何在理想情况下调用classify
的示例代码(输出是kludgey,因为它不会溢出非常大的输入):
def classifyRdd (subjects: RDD[Subject]): RDD[(String, Long)] = {
val classifier = new Classifier
subjects.foreach(subject => classifier.classifyInBatches(subject))
classifier.classifyRemaining
classifier.results
}
这样classifyInBatches
内部可以有这样的代码:
def classifyInBatches(subject: Subject) {
if (!internals.canAdd(subject)) {
partialResults.add(internals.processExisting)
}
internals.add(subject) // Assumption: at least one will fit.
}
我可以在Apache Spark中做些什么来允许这样的行为?
答案 0 :(得分:2)
尝试使用mapPartitions
方法,它允许map函数使用分区作为迭代器并生成输出的迭代器。
你应该可以这样写:
subjectsRDD.mapPartitions { subjects =>
val classifier = new Classifier
subjects.foreach(subject => classifier.classifyInBatches(subject))
classifier.classifyRemaining
classifier.results
}