使用spark和Im我发现当一个查询有很多连接操作并且spark需要做很多shuffle操作时,我正在寻找信息,为什么发生这种情况,但我没有找到具体的东西。你能帮忙解释这个吗?为什么加入和分组会影响数据在shuffle中的滑动量
3
A
回答
2
Spark洗牌只是在集群中的数据移动。因此,要求分区中不存在本地数据的转换将执行洗牌。查看连接,每个分区需要遍历整个连接的df以完成操作,因此基本上将连接的df移动到每个活动分区。同样的事情会发生在group by key中,所有相同的密钥需要在同一个分区中结束,所以shuffle会将它们移到那里。正如你可以看到这不是很好的性能,所以你应该尽量避免它。
2
在简单的话:
的数据分布在。
- Spark在分布式文件系统(如HDFS)上运行。由于它是一个分布式文件系统,数据遍布在集群中。
- RDD是分布式数据集的抽象,因此构成RDD的数据遍布在集群中。
有时,数据必须移动。
- 无论何时遇到具有相同密钥的行需要在一起的操作时,都要担心。
- 由于它是一个分布式文件系统,所以具有相同密钥的行将需要穿越群集(混洗)在一起。例如,当您想要通过密钥(
join
)合并两个RDD时,或者想要一起收集密钥的所有值并对其执行操作时(groupByKey
),就是这种情况。
需要旅行的数据量可能并不总是很多。为了您的具体情况:
的连接,如果RDDS是co-partitioned,或者如果我们确信,使用相同的按键排坐在一起,不会有过程中加入任何洗牌!
您可以通过切换到
reduceByKey
来减少groupByKey
操作中混洗的数据量。然而,这不是银弹,有些情况下你可能想要留在groupByKey
。
+0
嗨,谢谢你的回答。所以,当你说联合两个rdds的关键是发生在联接,火花自动创建多个RDD?例如,如果我们在spark上通过hdfs执行一个查询,或者通过spark加入一个组,spark会在spark sql方法中的sql语句中创建多于一个rdd? – jUsr
谢谢你的回答。我只是不明白你的分区是什么意思。例如,“需要数据在本地不在本地存在的任何转换将会......”。你可以解释吗? – jUsr
分区是集群中的实际作品。每个作业都在分区之间分配。您可以将其视为线程,只是跨集群。您可以在3个节点集群中的20个分区上传播Spark任务。这个并行是每个节点(JVM)中的工作,所以分区/工作者的总数是20。 “默认情况下,Spark为文件的每个块创建一个分区(HDFS中的块默认为64MB),但您也可以通过传递更大的值来请求更多的分区。” –