Hive 导入失败 [java.lang.OutOfMemoryError]

Posted

技术标签:

【中文标题】Hive 导入失败 [java.lang.OutOfMemoryError]【英文标题】:Hive import fail [java.lang.OutOfMemoryError] 【发布时间】:2017-07-19 12:39:02 【问题描述】:

我正在使用 bash 命令将 sql 数据库导入 hive 客户端节点上的 hive 数据库(使用 Hortonworks 数据平台):

$ hive -f tables.sql

我得到错误:

log4j:WARN No such property [maxFileSize] in org.apache.log4j.DailyRollingFileAppender.

Logging initialized using configuration in file:/etc/hive/2.6.1.0-129/0/hive-log4j.properties
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Arrays.java:3332)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(AbstractStringBuilder.java:124)
    at java.lang.AbstractStringBuilder.append(AbstractStringBuilder.java:448)
    at java.lang.StringBuilder.append(StringBuilder.java:136)
    at org.apache.hadoop.hive.cli.CliDriver.processReader(CliDriver.java:409)
    at org.apache.hadoop.hive.cli.CliDriver.processFile(CliDriver.java:429)
    at org.apache.hadoop.hive.cli.CliDriver.executeDriver(CliDriver.java:718)
    at org.apache.hadoop.hive.cli.CliDriver.run(CliDriver.java:685)
    at org.apache.hadoop.hive.cli.CliDriver.main(CliDriver.java:625)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.apache.hadoop.util.RunJar.run(RunJar.java:233)
    at org.apache.hadoop.util.RunJar.main(RunJar.java:148)

我尝试将 HADOOP_HEAPSIZE 从 1GB 增加到 4GB,但仍然出现错误。有什么想法吗?

【问题讨论】:

【参考方案1】:

OutOfMemoryError 来自 CliDriver#processReader(BufferedReader) 中的 Hive 代码库。

public int processReader(BufferedReader r) throws IOException 
  String line;
  StringBuilder qsb = new StringBuilder();

  while ((line = r.readLine()) != null) 
    // Skipping through comments
    if (! line.startsWith("--")) 
      qsb.append(line + "\n");
    
  

  return (processLine(qsb.toString()));

将从文件中读取的所有行添加到StringBuilder,然后执行它。这一定意味着您指定的输入文件非常大。是否可以将其拆分为多个较小的文件并分别执行,从而减少内存占用?

您提到这是一个 SQL 数据库的导入。 Apache Sqoop 可能更适合该用例。

【讨论】:

我找到了这个用于将 .sql 拆分为 table.sql 的小仓库:github.com/kedarvj/mysqldumpsplitter,我正在尝试 经过一些研究,Apache Scoop 似乎比我的 hive 导入命令更适合这项工作

以上是关于Hive 导入失败 [java.lang.OutOfMemoryError]的主要内容,如果未能解决你的问题,请参考以下文章

导入失败:java.io.IOException:无法运行程序“hive”:错误=2,没有这样的文件或目录

在hue 使用oozie sqoop 从mysql 导入hive 失败

hive 创建数据表失败

sqoop从hive导入数据到mysql时出现主键冲突

oozie sqoop 操作导入失败

JVM性能调优