【问题标题】:Spark SQL fails because "Constant pool has grown past JVM limit of 0xFFFF"Spark SQL 失败,因为“常量池已超过 JVM 限制 0xFFFF”
【发布时间】:2016-11-18 09:55:09
【问题描述】:

我在 EMR 4.6.0 + Spark 1.6.1 上运行此代码:

val sqlContext = SQLContext.getOrCreate(sc)
val inputRDD = sqlContext.read.json(input)

try {
    inputRDD.filter("`first_field` is not null OR `second_field` is not null").toJSON.coalesce(10).saveAsTextFile(output)
    logger.info("DONE!")
} catch {
    case e : Throwable => logger.error("ERROR" + e.getMessage)
}

saveAsTextFile的最后阶段,它失败并出现以下错误:

16/07/15 08:27:45 ERROR codegen.GenerateUnsafeProjection: failed to compile: org.codehaus.janino.JaninoRuntimeException: Constant pool has grown past JVM limit of 0xFFFF
/* 001 */
/* 002 */ public java.lang.Object generate(org.apache.spark.sql.catalyst.expressions.Expression[] exprs) {
/* 003 */   return new SpecificUnsafeProjection(exprs);
/* 004 */ }
(...)

可能是什么原因?谢谢

【问题讨论】:

  • 有趣。每个 java 类都有一个常量池,用于保存所有常量,甚至包括类似的方法名称。 u2 constant_pool_count,所以常量的最大数量是 0xFFFF。我使用简单的 json 来测试哪个不会引发异常。为什么这段代码会生成这么多常量?是否可以发布部分json数据?
  • @RockieYang 无法上传我的 json,但它包含大约 90 个字符串/数字字段。
  • 你只需要添加一个json。你有没有测试过它是否相关的行数?
  • @RockieYang 我刚刚解决了这个问题,你可以查看下面的答案。关于您的问题,该作业运行了大约 400GB~ 数据。

标签: java scala apache-spark amazon-emr


【解决方案1】:

通过删除数据框中所有未使用的列或仅过滤您实际需要的列来解决此问题。

事实证明 Spark Dataframe 无法处理超宽模式。没有具体的列数可能会导致 Spark 因“常量池已超过 JVM 限制 0xFFFF”而中断 - 这取决于查询类型,但减少列数有助于解决此问题。

根本原因在于 JVM 的 64kb 用于生成的 Java 类 - 另请参阅 Andrew 的回答。

【讨论】:

  • 我刚刚做了一个测试,如果只是简单的列,spark 可以在 100 列上工作。如果是嵌入结构多的复杂列,当字段总数超过一定数量时,最终会失败。你的json总共有多少个字段?
  • 一般大约 90 个,有些字段是嵌套的,所以总的来说我会说超过 100 个。
  • 它在你的 json 结构中一定很特别。我用 4000 个简单的列进行了测试,它可以工作。无论如何,你解决它很好。
  • 还是没有办法吗?
  • 这取决于您的工作流程/查询/转换等。您对 100 列的估计通常不正确。我们有一些具有 11,000 列的工作流,并且运行良好。其他一些工作流程在 3,000 列时遇到此问题。编辑答案。
【解决方案2】:

这是由于 Java 对生成的类超过 64Kb 的已知限制。

此限制已在 SPARK-18016 中得到解决,该限制已在 Spark 2.3 中修复 - 将于 2018 年 1 月发布。

【讨论】:

    【解决方案3】:

    为了将来参考,此问题已在 spark 2.3 中修复(正如 Andrew 指出的那样)。

    如果您在 Amazon EMR 上遇到此问题,请升级到发布版本 5.13 或更高版本。

    【讨论】:

    • 如果您将 AWS Glue 与 spark 版本 2.2.x 一起使用,祝您好运,了解新版本的发布日期。
    猜你喜欢
    • 2019-05-05
    • 2015-10-30
    • 1970-01-01
    • 2015-02-12
    • 2020-05-15
    • 1970-01-01
    • 2018-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多