繁体   English   中英

如何有效地加入任意数量的RDD?

[英]How to efficiently join an arbitrary number of RDDs?

使用RDD1.join(RDD2)加入两个RDD非常简单。 但是,如果我在List<JavaRDD>保留任意数量的RDD,我该如何有效地加入它们?

首先,请注意您无法加入JavaRDD 您需要使用以下方法获取JavaPairRDD

  • groupBy() (或keyBy()
  • cartesian()
  • [flat]mapToPair()
  • zipWithIndex() (很有用,因为它添加了没有的索引)
  • 等等

然后,一旦你有了你的清单,就可以像这样加入他们:

JavaPairRDD<Integer, String> linesA = sc.parallelizePairs(Arrays.asList(
                                            new Tuple2<>(1, "a1"),
                                            new Tuple2<>(2, "a2"),
                                            new Tuple2<>(3, "a3"),
                                            new Tuple2<>(4, "a4")));
JavaPairRDD<Integer, String> linesB = sc.parallelizePairs(Arrays.asList(
                                            new Tuple2<>(1, "b1"),
                                            new Tuple2<>(5, "b5"),
                                            new Tuple2<>(3, "b3")));
JavaPairRDD<Integer, String> linesC = sc.parallelizePairs(Arrays.asList(
                                            new Tuple2<>(1, "c1"),
                                            new Tuple2<>(5, "c6"),
                                            new Tuple2<>(6, "c3")));

// the list of RDDs
List<JavaPairRDD<Integer, String>> allLines = Arrays.asList(linesA, linesB, linesC);

// since we probably don't want to modify any of the datasets in the list, we will
// copy the first one in a separate variable to keep the result
JavaPairRDD<Integer, String> res = allLines.get(0);
for (int i = 1; i < allLines.size(); ++i) {  // note we skip position 0 !
    res = res.join(allLines.get(i))
    /*[1]*/  .mapValues(tuple -> tuple._1 + ':' + tuple._2);
}

[1]的线是重要的线,因为它映射了a

JavaPairRDD<Integer, Tuple2<String,String>>回到一个

JavaPairRdd<Integer,String>使其与其他连接兼容。

根据chrisw的回答,这可以像这样放入“一行”:

JavaPairRDD<Integer, String> res;
res = allLines.stream()
              .reduce((rdd1, rdd2) -> rdd1.join(rdd2).mapValues(tup -> tup._1 + ':' + tup._2))
              .get();  // get value from Optional<JavaPairRDD>

最后,关于表现的一些想法。 在上面的示例中,我使用字符串连接将连接的结果减少回相同类型的RDD。 如果你有很多RDD,你可以通过使用带有JavaPairRDD<Integer, StringBuilder> resfor loop版本来加快速度,你可以手动进行第一次连接。 如果需要,我会发布更多细节。

我不熟悉JavaRDD类/接口,但也许你可以使用Java 8中的高阶函数reduce来解决这个问题,请参阅https://docs.oracle.com/javase/tutorial/collections/streams/reduction。 HTML

final List<JavaRDD> list = getList(); // where getList is your list implementation containing JavaRDD instances

// The JavaRDD class provides rdd() to get the RDD
final JavaRDD rdd = list.stream().map(JavaRDD::rdd).reduce(RDD::join);

String类的示例如下: -

Stream.of("foo", "bar", "baz").reduce(String::concat);

哪个产生

foob​​arbaz

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM