在Spark

时间:2016-12-09 11:04:14

标签: apache-spark

我们正在尝试为RDD分配相同的执行程序和相同的分区程序以避免任何网络流量,并且像cogroup和join这样的shuffle操作没有任何阶段边界,并且所有转换都在一个阶段完成。

为了实现这一点,我们使用Java中的自定义RDD类(ExtendRDD.class)包装RDD,该类具有来自RDD.class(在scala中)的覆盖getPreferredLocation函数:

 public Seq<String> getPreferredLocations(Partition split){
        listString.add("11.113.57.142");
        listString.add("11.113.57.163");
        listString.add("11.113.57.150");
        List<String> finalList = new ArrayList<String>();
        finalList.add(listString.get(split.index() % listString.size()));               

        Seq<String> toReturnListString = scala.collection.JavaConversions.asScalaBuffer(finalList).toSeq();

        return toReturnListString;
    } 

有了这个,我们就可以控制spark的行为,看看它将RDD放在集群中的哪个节点。但现在的问题是,自分区器以来 对于这些RDD不同,spark认为它们与shuffle相关,并再次为这些shuffle操作创建多个阶段。我们尝试在同一个自定义RDD中覆盖相同RDD.class的分区方法:

public Option<Partitioner> partitioner() {
        Option<Partitioner> optionPartitioner = new Some<Partitioner>(this.getPartitioner());
        return optionPartitioner;
    } 

对于将它们放在同一阶段的火花,必须考虑这些RDD来自同一个分区。 我们的分区方法似乎不起作用,因为spark为2个RDD提供了不同的分区,并为shuffle操作创建了多个阶段。

我们使用自定义RDD将scala RDD包装为:

ClassTag<String> tag = scala.reflect.ClassTag$.MODULE$.apply(String.class);
RDD<String> distFile1 = jsc.textFile("SomePath/data.txt",1);
ExtendRDD<String> extendRDD = new ExtendRDD<String>(distFile1, tag);

我们以类似的方式创建另一个自定义RDD,并从该RDD中获取PairRDD(pairRDD2)。然后我们尝试使用partitionBy函数将与extendRDD对象相同的分区器应用于PairRDDFunction对象,然后将cogroup应用于:

RDD<Tuple2<String, String>> pairRDD = extendRDD.keyBy(new KeyByImpl());
PairRDDFunctions<String, String> pair = new PairRDDFunctions<String, String>(pairRDD, tag, tag, null);
pair.partitionBy(extendRDD2.getPartitioner());
pair.cogroup(pairRDD2);

所有这些似乎都不起作用,因为当遇到cogroup转换时,spark会产生多个阶段。

有关如何将相同的分区程序应用于RDD的任何建议?

0 个答案:

没有答案