【问题标题】:Spark SQL: why does not Spark do broadcast all the timeSpark SQL:为什么 Spark 不一直广播
【发布时间】:2019-12-09 04:44:23
【问题描述】:

我在 aws s3 和 emr 上使用 Spark 2.4 开展一个项目,我有一个包含两大部分数据的左连接。 spark执行不稳定,经常因为内存问题而失败。

集群有 10 台 m3.2xlarge 类型的机器,每台机器有 16 个 vCore、30 GiB 内存、160 GB SSD 存储。

我有这样的配置:

          "--executor-memory",
          "6512M",
          "--driver-memory",
          "12g",
          "--conf",
          "spark.driver.maxResultSize=4g",
          "--conf",
          "spark.sql.autoBroadcastJoinThreshold=1073741824",

left join 发生在 150GB 的左侧和 30GB 左右的右侧之间,因此有很多 shuffle。我的解决方案是将右侧切到足够小,例如 1G,因此将广播数据而不是随机播放。唯一的问题是在第一次左连接之后,左侧已经有来自右侧的新列,所以下面的左连接将有重复列,如 col1_right_1、col2_right_1、col1_right_2、col2_right_2,我必须重命名 col1_right_1/col1_right_2到 col1_left,col2_right_1/col2_right_2 到 col2_left。

所以我想知道,为什么 Spark 允许随机播放,而不是到处使用广播。广播不应该总是比随机播放快吗?为什么 Spark 不像我说的那样加入,将一侧切成小块并播放?

【问题讨论】:

    标签: apache-spark pyspark-sql


    【解决方案1】:

    让我们看看这两个选项。 如果我理解正确您正在为数据帧的每个片段执行广播和连接,其中片段的大小是最大广播阈值。 这里的优点是您基本上只通过网络发送一个数据帧,但您正在执行多个连接。每个要执行的连接都有一个开销。 From:

    一旦广播的数据集在执行器机器上可用,它 与另一个数据集的每个分区连接。也就是说,对于 的每一行(在每个分区中)的连接列的值 其他Dataset,从广播中取出对应的行 数据集和连接被执行。

    这意味着对于每批广播连接,在每个分区中,您都必须查看整个其他数据集并执行连接。

    Sortmerge 或散列连接必须执行 shuffle(如果数据集没有平均分区),但它们的连接效率更高。

    【讨论】:

    • 我明白了。广播会花费更多时间,但上边是RAM上的压力会更小,所以失败的可能性更小。所以如果我们更喜欢稳定的应用程序,也许广播会更好,而且成本是更长的处理时间,对吗?
    • 可能是,但我不确定这是否是最好的方法。您可能有兴趣查看此response 的第 4 步。比较这两种解决方案可能会很有趣。
    猜你喜欢
    • 1970-01-01
    • 2018-11-12
    • 2020-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-12
    • 1970-01-01
    相关资源
    最近更新 更多