【问题标题】:Why join in spark in local mode is so slow?为什么在本地模式下加入 spark 这么慢?
【发布时间】:2016-12-25 07:07:58
【问题描述】:

我在本地模式下使用 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.memory 30g
  4. spark.driver.memory 30g
  5. spark.serializer org.apache.spark.serializer.KryoSerializer
  6. spark.sql.shuffle.partitions 16

唯一的执行者是驱动程序本身。在提取数据帧时,我将其划分为 32 个(也尝试了 16、64、50、100、200)个部分。我已经看到使用数据帧 A 提取的 Stage 的随机写入内存为 100 MB。所以为了避免洗牌,我为数据帧和广播数据帧 B(更小)做了 16 个初始分区,但这没有帮助。仍然有随机写入内存。我为此使用了broadcast(B) 语法。 我做错了吗?为什么仍然存在洗牌? 此外,当我看到事件时间线时,它显示在任何时间点都只有四个内核正在处理。虽然我有一台2核*4处理器的机器。为什么会这样?

【问题讨论】:

标签: apache-spark pyspark apache-spark-sql spark-dataframe


【解决方案1】:

简而言之,“加入”洗牌,这里最大的问题是您的数据在分区上分布的均匀程度(例如参见 https://0x0fff.com/spark-architecture-shuffle/https://www.slideshare.net/SparkSummit/handling-data-skew-adaptively-in-spark-using-dynamic-repartitioning 和谷歌问题)。 提高效率的可能性很小:

  • 更多地考虑您的数据(A 和 B)并明智地对数据进行分区;
  • 分析一下,你的数据有偏差吗?;
  • 进入 UI 并查看任务时序;
  • 为在“加入”期间只有少数几个分区从数据集 A shuffle 和少数 B 分区的分区选择这样的键;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 2010-10-05
    • 2020-11-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多