我正在构建一个读取1.5 G数据并进行翻译的应用程序。我的代码框架如下。
//这里我传递一个id列表来读取4000个文件并形成所有记录的联合RDD并将其作为unionbioSetId返回
的run(){
JavaRDD<String> unionbioSetId = readDirectory(ctx, groupAID, groupBID);
JavaRDD<String> temp= unionbioSetId.coalesce(6, false);
JavaPairRDD<String, Tuple3<Double, Double, Double>> flatRDD = temp.flatMapToPair(
new PairFlatMapFunction<String, String, String>() {
return Arrays.asList(new Tuple2<String, String>(key,value));
}}).groupByKey().mapToPair(new PairFunction<Tuple2<String, Iterable<String>>, // input
String, // K
Tuple3<Double, Double, Double> // V
>() {
public Tuple2<String, Tuple3<Double, Double, Double>> call(
Tuple2<String, Iterable<String>> value) {
}).filter(new Function<Tuple2<String, Tuple3<Double, Double, Double>>, Boolean>() {
}});// group by key and map to pair,sort by key
}
String hadoopOutputPathAsString = directory;
flatRDD.saveAsTextFile(hadoopOutputPathAsString);
}
} /////////////// 执行人数:9 驱动程序内存:2g 执行者记忆:6g 执行者核心:12
我的程序运行速度比map / reduce(相同的代码框架)慢。任何人都可以帮助我优化上面的代码框架,使其更快。
答案 0 :(得分:3)
请勿致电coalesce
。您不需要更少的分区,您需要更多分区。您有108个工作核心,但如果使用6个分区,则只使用其中的6个。根据经验,您至少需要 3 * num_executors
* cores_per_executor
= 324 分区。
JavaRDD<String> temp = unionbioSetId.repartition(350);
或者根本不要改变分区数量。读取文件时,数据将通过Hadoop拆分进行分区。在许多情况下,这会提供良好的布局,您可以避免重新分区的成本。
一次阅读文件,而不是单独阅读,然后结合他们的联盟:sc.textFile("file1,file2,file3,...")
或sc.textFile("dir/*")
。这也可能会产生性能差异。