如何物理分区数据以避免在Spark SQL连接中进行随机播放

时间:2016-10-24 19:07:23

标签: apache-spark-sql

我需要加入5个中等大小的表(每个大约80 gb)和一个大输入数据~800 gb。所有数据都存在于HIVE表中。 我正在使用Spark SQL 1.6.1来实现这一目标。 加入需要40分钟才能完成 --num-executors 20 --driver-memory 40g --executor-memory 65g --executor-cores 6。所有联接都是排序合并外连接。也看到很多洗牌事件发生了。

我将hive中的所有表格分成相同数量的存储区,以便所有表中的类似键在首先加载数据时会转到相同的spark分区。但似乎火花无法理解。

还有其他任何方式我可以进行物理分区吗?在Hive中排序数据(没有部分文件),这样火花就会知道在从hive本身加载数据时对分区键进行分区,并在同一分区中进行连接而不会使数据混乱?从hive加载数据后,这将避免额外的重新分区。

1 个答案:

答案 0 :(得分:0)

首先,Spark Sql 1.6.1还不支持hive存储桶。 因此,在这种情况下,我们将保留Spark级别操作,以确保在加载数据时所有表必须转到相同的spark分区。 Spark API提供了重新分区和sortWithinPartitions来实现相同的功能。 e.g

val part1 = df1.repartition(df1(“key1”))。sortWithinPartitions(df1(“key1”))

以同样的方式,您可以为剩余的表分配几代分区,并将它们连接到在分区内排序的密钥。

这将使连接“随机播放”操作,但需要大量的计算成本。如果操作将在后续执行,则缓存数据帧(您可以为新创建的分区执行缓存操作)执行得更好。希望这有帮助。