2016-12-25 52 views
2

我在本地模式下使用spark,并且一个简单的连接花费的时间太长。我已经提取了两个数据帧:A(8列和230万行)和B(8列和120万行),并使用A.join(B,condition,'left')加入它们,并最终调用动作。它创建了三个阶段的单个作业,每个阶段提取两个数据帧,一个用于加入。令人惊讶的是,提取数据帧A的阶段花费大约8分钟,而数据帧B花费1分钟。并且连接在几秒钟内发生。我的重要配置设置:为什么在本地模式下加入火花很慢?

  1. spark.master本地[*]
  2. spark.driver.cores 8
  3. spark.executor.memory30克
  4. spark.driver.memory30克
  5. 火花.serializer org.apache.spark.serializer.KryoSerializer
  6. spark.sql.shuffle.partitions 16

唯一的执行者是驱动程序本身。在提取数据帧的同时,我将它分区为32(也试过16,64,50,100,200)部分。我已经看到,使用数据帧A提取将shuffle写入内存为100 MB。因此,为了避免混洗,我为数据帧和广播数据帧B(较小)创建了16个初始分区,但这并没有帮助。还有洗牌写入记忆。我已经使用broadcast(B)语法。 我做错了什么?为什么洗牌仍然存在?另外,当我看到事件时间线,它显示只有四个核心在任何时间点处理。虽然我有一个2core * 4处理器的机器。 这是为什么?

+0

输入的大小是多少? – Yaron

+0

数据帧A包含280MB,对于B –

+0

也是140MB这些都是非常小的数据集...也许这样? https://bzhangusc.wordpress.com/2015/06/10/why-your-join-is-so-slow/ – mathtick

回答

1

总之,“加入” < =>洗牌,这里最大的问题是如何被均匀分布在分区数据(例如见https://0x0fff.com/spark-architecture-shuffle/https://www.slideshare.net/SparkSummit/handling-data-skew-adaptively-in-spark-using-dynamic-repartitioning和只是谷歌的问题)。 提高效率的几种可能性:

  • 想想更多关于您的数据(A和B)和明智的分区数据;
  • 分析,你的数据是否倾斜?
  • 进入UI并查看任务计时;
  • 选择这样的密钥用于“join”期间的分区只有少数几个分区来自数据集A洗牌而只有少数B分区;