工作失败“没有足够的内存来构建哈希映射”错误

您应该使用自适应查询执行而不是显式的广播提示上面的砖运行时11.3 LTS和执行连接。

写的saritha.shivakumar

去年发表在:2023年5月12日
删除

信息

本文适用于砖运行时11.3 LTS及以上。


问题

您正在运行SparkSQL / PySpark代码使用广播提示。需要花费很长的时间来运行比以前砖运行时和/或失败的记忆错误消息。

示例代码:

df.join(广播(bigDf) .write.mode .parquet(“覆盖”)(“路径”)

错误信息:

工作阶段失败而终止:没有足够的内存来构建造成的散列映射:没有足够的内存来构建散列映射


如果你检查SQL选项卡下的执行计划在Apache火花UI,它表示失败发生在一个执行人广播加入。

导致

遗嘱执行人一边播放加入(ejb)是一种增强了运行时11.3 LTS砖。它优化广播的方式加入功能。以前,广播连接依赖的火花司机广播的一方加入。虽然这种方法有效,它提出了以下挑战:

  • 单点故障:司机,集群中的所有查询的协调员,面临失败的风险增加,由于JVM的内存错误当用于广播所有并发查询。在这种情况下,所有查询同时运行在集群上可能会受到影响和潜在的失败。
  • 有限的灵活性增加默认播放加入阈值:内存不足错误司机的风险(由于并发广播)很难增加默认播放加入阈值(目前10 mb 30 mb的静态和动态),因为这将添加更多的内存压力驱动程序和提升失败的风险。


EBJ增强解决这些挑战,把内存压力从司机的执行人。这不仅消除了单点故障,还允许增加默认播放加入门槛,由于总集群失败的风险降低。

启用了EBJ,不幸的是,查询,使用显式广播提示现在可能失败。这是更有可能与一个更大的数据集。

遇到的问题是相关的内存消耗在驾驶员一侧广播管理。使用的内存驾驶员一侧广播控制spark.driver.maxResultSize。在早期版本中,用于广播的内存中没有显式跟踪和占内存管理器的任务。这意味着这个任务可能低估了内存使用。因此,较大的作业可能看似随机失败,由于内存不足错误,而另一些人会成功是因为运气。

启用了EBJ,为广播散列映射分配的内存是准确地跟踪和扣除任务的内存管理器的可用内存。这个改进降低了内存泄漏的风险和JVM的内存错误。因此,大型广播可能以不同的方式处理,而且还提高了可靠性。

解决方案

跟踪内存使用ejb是至关重要的防止JVM的内存错误,从而导致所有并发查询节点的失败。

而不是使用广播提示,你应该让自适应查询执行(AWS|Azure|GCP)选择加入适用于工作量根据所处理的数据的大小。

这篇文章有用吗?