我复制了sortByKey
的正文并重命名为sortByKey2
,但它们会给出不同的结果。为什么第一个结果在这里错了?这是在日食中运行的。我重新启动了eclipse,但仍然得到了错误的结果。
package test.spark
import org.apache.spark.sql.SparkSession
object RddTests {
var spark = SparkSession.builder().appName("rdd-test").master("local[*]")
.enableHiveSupport()
.getOrCreate()
val sc = spark.sparkContext
def main(args: Array[String]) {
//mapValues
//combineWithKey
//foldByKey
sortByKey
sortByKey2
}
def sortByKey() {
val people = List(("Mobin", 2), ("Mobin", 1), ("Lucy", 2), ("Amy", 1), ("Lucy", 3), ("Lucy", 1))
val rdd = sc.parallelize(people)
val sortByKeyRDD = rdd.sortByKey()
println;println("sortByKeyRDD")
sortByKeyRDD.foreach(println)
}
def sortByKey2() {
val people = List(("Mobin", 2), ("Mobin", 1), ("Lucy", 2), ("Amy", 1), ("Lucy", 3), ("Lucy", 1))
val rdd = sc.parallelize(people)
val sortByKeyRDD = rdd.sortByKey()
println;println("sortByKeyRDD2")
sortByKeyRDD.foreach(println)
}
}
输出结果为:
[Stage 0:> (0 + 0) / 4]
sortByKeyRDD
(Mobin,2)
(Mobin,1)
(Amy,1)
(Lucy,2)
(Lucy,3)
(Lucy,1)
sortByKeyRDD2
(Amy,1)
(Mobin,2)
(Mobin,1)
(Lucy,2)
(Lucy,3)
(Lucy,1)
答案 0 :(得分:5)
foreach
不保证以任何特定顺序处理元素。如果您执行sortByKeyRDD.collect.foreach(println)
,您将按顺序查看结果,但这假设您的数据适合驱动程序内存。
如sortByKey
文档中所述:
调用收集或保存生成的RDD将返回或输出有序的记录列表
[编辑]使用toLocalIterator
代替collect
将驱动程序内存要求限制为最大的单个分区。感谢Deflater在评论中指出这一点。
答案 1 :(得分:0)
重要的是要在这里了解 foreach()或 sortByKey()之类的方法是如何工作的。
当您尝试对数据进行排序并喜欢使用 foreach(System.out :: println)打印输出时,驱动程序将此方法分配给每个分区(即,在群集OR的情况下为节点)如果是单机,则为多线程)。因此,每个分区都在本地执行foreach。这意味着您将看不到想要的输出。
人们建议的可能的解决方案,在Bigdata中不是正确的解决方案
sortByKeyRDD.coalesce(1).foreach(System.out::println);
或
sortByKeyRDD.collect().forEach(System.out::println);
以上解决方案仅出于理解目的,我不建议使用它。如果数据很大,则可能会内存不足,因为它尝试在驱动程序中收集所有数据以打印输出。