首页 > 解决方案 > 10个最常见的女性名字 - 顺序变化

问题描述

我正在 Databricks 中进行练习,下面的代码每次运行时都会以不同的顺序返回 firstName。请解释每次运行的顺序不同的原因:

val peopleDF = spark.read.parquet("/mnt/training/dataframes/people-10m.parquet")

id:integer
firstName:string
middleName:string
lastName:string
gender:string
birthDate:timestamp
ssn:string
salary:integer

/* Create a DataFrame called top10FemaleFirstNamesDF that contains the 10 most common female first names out of the people data set.*/
import org.apache.spark.sql.functions.count
val top10FemaleFirstNamesDF_1 = peopleDF.filter($"gender"=== "F").groupBy($"firstName").agg(count($"firstName").alias("cnt_firstName")).withColumn("cnt_firstName",$"cnt_firstName".cast("Int")).sort($"cnt_firstName".desc).limit(10)
val top10FemaleNamesDF = top10FemaleFirstNamesDF_1.orderBy($"firstName")

有些运行断言通过,有些运行断言失败:

lazy val results = top10FemaleNamesDF.collect()

dbTest("DF-L2-names-0", Row("Alesha",    1368), results(0))  
// dbTest("DF-L2-names-1", Row("Alice",     1384), results(1))
// dbTest("DF-L2-names-2", Row("Bridgette", 1373), results(2))
// dbTest("DF-L2-names-3", Row("Cristen",   1375), results(3))
// dbTest("DF-L2-names-4", Row("Jacquelyn", 1381), results(4))
// dbTest("DF-L2-names-5", Row("Katherin",  1373), results(5))
// dbTest("DF-L2-names-5", Row("Lashell",   1387), results(6))
// dbTest("DF-L2-names-7", Row("Louie",     1382), results(7))
// dbTest("DF-L2-names-8", Row("Lucille",   1384), results(8))
// dbTest("DF-L2-names-9", Row("Sharyn",    1394), results(9)) 

println("Tests passed!")

标签: scalaapache-spark

解决方案


问题可能出在limit 10. 由于 spark 的分布式特性,你不能假设它每次运行limit函数都会给你相同的结果。Spark 可能会在不同的运行中找到不同的分区,从而为您提供 10 个元素。如果底层数据被拆分到多个分区,那么每次评估它时,limit 可能会从不同的分区中提取。

但是,我确实意识到您是先对数据进行排序,然后再对其进行限制。当底层 rdd 被排序时,limit 函数应该确定性地返回。对于未排序的数据,它可能是不确定的。

查看查询的物理计划是值得的。


推荐阅读