Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala distinct()是否对数据集进行排序?_Scala_Apache Spark - Fatal编程技术网

Scala distinct()是否对数据集进行排序?

Scala distinct()是否对数据集进行排序?,scala,apache-spark,Scala,Apache Spark,我正在编写一个预处理应用程序,在其他转换和操作中,在将数据集写入HDFS之前对其进行排序。一个新的请求需要我对数据集进行重复数据消除,所以我希望在一个阶段中通过排序来完成。我的理解是,为了有效地执行重复数据消除,排序是必要的(也许我在这方面错了,没有对其进行太多研究,只是看起来很自然) 出于某些原因(MapType列在输出模式中),我首先在sort之前的阶段测试了distinct,我认为我会在以后去掉MapType列,以便将它们合并在一起 发生的情况是,跳过了排序的第二阶段,就好像数据集已经排

我正在编写一个预处理应用程序,在其他转换和操作中,在将数据集写入HDFS之前对其进行排序。一个新的请求需要我对数据集进行重复数据消除,所以我希望在一个阶段中通过排序来完成。我的理解是,为了有效地执行重复数据消除,排序是必要的(也许我在这方面错了,没有对其进行太多研究,只是看起来很自然)

出于某些原因(
MapType
列在输出模式中),我首先在
sort
之前的阶段测试了
distinct
,我认为我会在以后去掉
MapType
列,以便将它们合并在一起


发生的情况是,跳过了排序的第二阶段,就好像数据集已经排序一样。这对我来说是有意义的,但文档中的任何地方都不支持(AFAIK),我不知道预期的行为是否稳定(我不想把它推到生产中,只是为了意识到我突然要做两个昂贵的阶段:
sort
distinct
)。对于如何实现
sort
和/或
distinct
有更多见解吗?

在spark中,
distinct
通常所有聚合操作(如
groupBy
都不会对数据进行排序。我们可以使用
explain
功能轻松检查这一点

//让我们用[0,4]中的5个元素生成一个df,以便至少有一个副本
val data=spark.范围(5)。选择(地板(rand()*4)为“r”)
data.distinct.explain
==实际计划==
*HashAggregate(键=[r#105L],函数=[])
+-交换哈希分区(r#105L,200)
+-*HashAggregate(键=[r#105L],函数=[])
+-*项目[楼层((兰特(7842501052366484791)*5.0))为r#105L]
+-*范围(0,10,步长=1,分段=2)
HashAggregate
+
Exchange
意味着对元素进行散列和洗牌,以使具有相同散列的元素位于同一分区中。然后,对具有相同散列的元素进行比较和重复数据消除。因此,处理后不会对数据进行排序。让我们检查一下:

data.distinct.show()
+---+                                                                           
|r|
+---+
|  0|
|  3|
|  2|
+---+
现在,让我们谈谈您对性能的担忧。如果您在重复数据消除后进行排序,则会发生以下情况

data.distinct.orderBy(“r”)。解释
==实际计划==
*排序[r#227L ASC NULLS FIRST],true,0
+-Exchange范围分区(r#227L ASC空值优先,200)
+-*HashAggregate(键=[r#227L],函数=[])
+-交换哈希分区(r#227L,200)
+-*HashAggregate(键=[r#227L],函数=[])
+-*项目[楼层((兰特(-8636860894475783181)*4.0))为r#227L]
+-*范围(0,5,步长=1,分段=2)
我们可以看到数据被洗牌以消除重复(
Exchange hashpartitioning
),然后再次洗牌以进行排序(
Exchange rangepartitioning
)。这相当昂贵。这是因为排序需要按范围进行洗牌,以便同一范围内的元素最终位于同一分区中,然后可以进行排序。但是,我们可以更智能地在重复数据消除之前进行排序:

data.orderBy(“r”).distinct.explain
==实际计划==
*HashAggregate(键=[r#227L],函数=[])
+-*HashAggregate(键=[r#227L],函数=[])
+-*排序[r#227L ASC NULLS FIRST],true,0
+-Exchange范围分区(r#227L ASC空值优先,200)
+-*项目[楼层((兰特(-8636860894475783181)*4.0))为r#227L]
+-*范围(0,5,步长=1,分段=2)

只剩下一次交换。事实上,spark知道在按范围进行洗牌后,重复的元素位于同一分区中。因此它不会触发新的洗牌。

能否发布一个最小的代码片段,以便我们了解所有详细信息?我们举个例子,我想知道您是否需要按同一列排序和消除重复,可能是按所有列进行排序…我需要按所有列进行重复数据消除,因为我只需要消除“技术重复项”(在数据转储作业失败并再次启动f.e.)中创建的重复项。但我只按2列进行排序。本质上,我在做类似于
数据集的事情。(一些转换)。排序('id','timestamp')。write.parquet(…)“
我需要将
distinct()
放在那里的某个地方。将它放在
排序之后并不方便,但如果它有助于提高性能,我会这样做