rdd.sortByKey给出了错误的结果

时间:2017-09-08 02:39:40

标签: scala apache-spark rdd

我复制了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)

2 个答案:

答案 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);

以上解决方案仅出于理解目的,我不建议使用它。如果数据很大,则可能会内存不足,因为它尝试在驱动程序中收集所有数据以打印输出。