2016-05-30 62 views

回答

2

Spark洗牌只是在集群中的数据移动。因此,要求分区中不存在本地数据的转换将执行洗牌。查看连接,每个分区需要遍历整个连接的df以完成操作,因此基本上将连接的df移动到每个活动分区。同样的事情会发生在group by key中,所有相同的密钥需要在同一个分区中结束,所以shuffle会将它们移到那里。正如你可以看到这不是很好的性能,所以你应该尽量避免它。

+0

谢谢你的回答。我只是不明白你的分区是什么意思。例如,“需要数据在本地不在本地存在的任何转换将会......”。你可以解释吗? – jUsr

+0

分区是集群中的实际作品。每个作业都在分区之间分配。您可以将其视为线程,只是跨集群。您可以在3个节点集群中的20个分区上传播Spark任务。这个并行是每个节点(JVM)中的工作,所以分区/工作者的总数是20。 “默认情况下,Spark为文件的每个块创建一个分区(HDFS中的块默认为64MB),但您也可以通过传递更大的值来请求更多的分区。” –

2

在简单的话:

  1. 的数据分布在。

    • Spark在分布式文件系统(如HDFS)上运行。由于它是一个分布式文件系统,数据遍布在集群中。
    • RDD是分布式数据集的抽象,因此构成RDD的数据遍布在集群中。
  2. 有时,数据必须移动。

    • 无论何时遇到具有相同密钥的行需要在一起的操作时,都要担心。
    • 由于它是一个分布式文件系统,所以具有相同密钥的行将需要穿越群集(混洗)在一起。例如,当您想要通过密钥(join)合并两个RDD时,或者想要一起收集密钥的所有值并对其执行操作时(groupByKey),就是这种情况。
  3. 需要旅行的数据量可能并不总是很多。为了您的具体情况:

    • 的连接,如果RDDS是co-partitioned,或者如果我们确信,使用相同的按键排坐在一起,不会有过程中加入任何洗牌!

    • 您可以通过切换到reduceByKey来减少groupByKey操作中混洗的数据量。然而,这不是银弹,有些情况下你可能想要留在groupByKey

+0

嗨,谢谢你的回答。所以,当你说联合两个rdds的关键是发生在联接,火花自动创建多个RDD?例如,如果我们在spark上通过hdfs执行一个查询,或者通过spark加入一个组,spark会在spark sql方法中的sql语句中创建多于一个rdd? – jUsr