[英]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> res
的for 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);
哪个产生
foobarbaz
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.