如何在 Hive 输出查询结果时解决 Amazon EMR 上的“OutOfMemoryError”Hive Java 堆空间异常?
我在 Amazon EMR 上运行 Apache Hive 查询。Hive 在输出查询结果时引发 OutOfMemoryError 异常。
简短描述
OutOfMemoryError 异常通常在 hive-server2、Hive 元存储或客户端没有足够的堆空间时在 INSERT OVERWRITE 命令期间发生。要解决此问题,请增加 JVM 的最大内存分配或提高 HADOOP_HEAPSIZE。
解决方法
使用以下一个或多个解决方案解决 OutOfMemoryError 异常。
**注意:**这些解决方法不涵盖在 Apache Tez 容器内存优化期间发生的 OutOfMemoryError 异常。
增加 JVM 的最大内存分配
当您启动 Hive shell 时,默认会分配 1 GB 内存。最大内存分配由 -Xmx 参数定义。如果进程尝试使用超过最大值的内存,则 Hive 会尝试终止该进程并引发 OutOfMemoryError 异常。要解决此问题,请在 Hive shell 脚本中增大 -Xmx 值(单位 MB),然后再次运行 Hive 查询。
识别日志中的 OutOfMemoryError
检查您的日志位置是否存在以下错误(例如:/mnt/var/log/hive/user/hadoop/hive.log):
# java.lang.OutOfMemoryError: Java heap space # -XX:OnOutOfMemoryError="kill -9 %p" # Executing /bin/sh -c "kill -9 12345"... Killed
如果看到此错误消息,则表示 JVM 堆空间内存不足。在 /etc/hive/conf/hive-env.sh 中增加 Hive CLI 服务的 HADOOP_HEAPSIZE,如下例中所示。您还可以使用进行 hive-env 分类的 Amazon EMR 重新配置 API 增加 HADOOP_HEAPSIZE。默认值是 1000。根据使用案例的需要增加它。然后,再次运行 Hive 查询。
export HADOOP_HEAPSIZE=2048
**重要提示:**重启这些服务后,此设置将应用于 hive-server2、Hive 元存储和 Hive CLI。(可选)您可以为这些服务中的每一个设置单独的值。
创建集群时更新内存分配
Amazon EMR 提供配置 API 操作,以便在您使用配置对象更新集群时更新默认配置。根据您的使用场景更新 HADOOP_HEAPSIZE 值:
{ "Classification": "hive-env", "Properties": {}, "Configurations": [ { "Classification": "export", "Properties": { "HADOOP_HEAPSIZE": "2048" }, "Configurations": [] } ] }
更新正在运行的集群上的内存分配
您可以通过使用 SSH 或 Amazon EMR 重新配置 API 连接到主模式来增加正在运行的集群上的 HADOOP_HEAPSIZE 的值。Amazon EMR 重新配置 API 仅适用于 Amazon EMR 发行版 5.21 及更高版本。如果内存更新是通过 SSH 对集群进行的,则必须重新启动 Hive 服务才能使更改生效。
Beeline 或 SQL Workbench/J
1. 如果您从 Beeline 或 SQL Workbench/J 运行相同的查询,请检查 /mnt/var/log/hive/hive-server2.log 和 hive-server2.out 中是否存在堆空间垃圾回收错误。例如:
Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://emr-analytics_master.abc.aws.> select id, name, x.* from mydb.location a, curated_admin.nxpepnd1_tpn_prvdr_pra_fclt b, curated_admin.test_table c where a.test = b._id and a._id = b._id and b._prod_id = c.prod_f_id; # # java.lang.OutOfMemoryError: Java heap space # -XX:OnOutOfMemoryError="kill -9 %p" # Executing /bin/sh -c "kill -9 27745"... Killed
2. 如果找到类似的错误,请在 /etc/hive/conf/hive-env.sh 中增加 hive-server2 的 HADOOP_HEAPSIZE。此设置也适用于 Hive 元存储和 Hive 客户端。
export HADOOP_HEAPSIZE=2048
(可选)使用条件语句为 hive-server2、元存储和客户端指定不同的堆大小。例如:
export HIVE_CLIENT_HEAPSIZE=1024 export HIVE_METASTORE_HEAPSIZE=2048 export HIVE_SERVER2_HEAPSIZE=3072 if [ "$SERVICE" = "metastore" ] then export HADOOP_HEAPSIZE=$HIVE_METASTORE_HEAPSIZE elif [ "$SERVICE" = "hiveserver2" ] then export HADOOP_HEAPSIZE=$HIVE_SERVER2_HEAPSIZE export HADOOP_OPTS="$HADOOP_OPTS -server -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -XX:+PrintGCDateStamps -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/var/log/hive" else export HADOOP_HEAPSIZE=$HIVE_CLIENT_HEAPSIZE fi
3. 更新这些设置后再次运行 Hive 查询。如果仍出现 OutOfMemoryError 异常,并且您正在同时运行多个客户端,请继续执行步骤 4。如果仍出现 OutOfMemoryError 异常,并且您未同时运行多个客户端,请跳到步骤 8。
4. 根据使用案例的需要为每个客户端增大 -Xmx 参数。
5. 选择适用于您的使用场景的垃圾回收器,方法是在 HADOOP_OPTS 行中添加 -XX:+UseParNewGC(新的并行垃圾回收器)或 -XX:+UseConcMarkSweepGC(并发标记扫描垃圾回收器),如以下示例所示。有关选择垃圾回收器的更多信息,请参阅 Java 文档中的垃圾回收和 Java HotSpot VM 选项。
export HADOOP_HEAPSIZE=2048 if [ "$SERVICE" = "cli" ]; then if [ -z "$DEBUG" ]; then export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xmx12288m -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:+useParNewGC -XX:-useGCOverheadLimit" else export HADOOP_OPTS="$HADOOP_OPTS -XX:NewRatio=12 -Xmx12288m -Xms10m -XX:MaxHeapFreeRatio=40 -XX:MinHeapFreeRatio=15 -XX:-useGCOverheadLimit" fi fi
6. 如果在指定的时间内未成功完成垃圾收集,则 Hive 会引发 OutOfMemoryError 异常。要删除时间限制,请删除 -XX:-UseGCOverheadLimit 或将其替换为 -XX:+UseGCOverheadLimit。(可选)修改 -XX:-UseGCOverheadLimit 以指定垃圾收集的新时间限制。有关更多信息,请参阅 Java 文档中的并行收集器。
7. 再次运行 Hive 查询。如果 Hive 在运行时在终端上引发堆空间错误,或者如果 hive.log 或 hive-server2.log 中没有错误,则您的 Hive 客户端可能已用尽内存。例如:
Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://emr-analytics_master.abc.aws.> select id, name, x.* from mydb.location a, curated_admin.nxpepnd1_tpn_prvdr_pra_fclt b, curated_admin.test_table c where a.test = b._id and a._id = b._id and b._prod_id = c.prod_f_id; # # java.lang.OutOfMemoryError: Java heap space # -XX:OnOutOfMemoryError="kill -9 %p" # Executing /bin/sh -c "kill -9 27745"... Killed
8. 要解决此错误,请增加客户端内存,然后再次运行查询。
9. 如果 Hive 仍引发 OutOfMemoryError 异常,请为客户端完成以下步骤。
Beeline:
默认情况下,Beeline 在输出到 stdout 之前会尝试缓冲整个输出关系。在输出关系较大时,此行为会导致 OutOfMemoryError 异常。要解决 Beeline 中的 OutOfMemoryError 异常,请使用以下命令启动 Beeline,然后重试 Hive 查询:
beeline --incremental=true
SQL Workbench/J:
在 32 位 Java 运行时环境(JRE)中,默认情况下应用程序可以使用最高 1 GB 的内存。在 64 位 JRE 中,默认情况下,应用程序最多可以使用 65% 的可用物理内存。要验证应用程序的可用内存量,请在选择帮助,然后选择关于。
- **对于 macOS:**请根据需要在 Info.plist 文件中增大 -Xmx1024m 值。Info.plist 通常位于 /Applications/SQLWorkbenchJ2.app/Contents 目录下。例如,要将应用程序的可用内存量增加一倍,请将值从 -Xmx1024m 更改为 -Xmx2048m。然后,再次运行查询。
- 对于 Windows:请创建 INI 文件,然后向该 INI 文件添加 vm.heapsize.preferred 参数,以增加应用程序的可用内存量。
如果您使用的是 Shell 脚本或批处理脚本,则可以在安装 SQL Workbench/J 时增加可用内存。以下示例中的命令将在安装期间创建 3 GB 的可用内存:
java -Xmx3g -jar sqlworkbench.jar
**注意:**如果 OutOfMemoryError 异常发生在客户端而不是 hive-server2 或 Hive CLI 上,请将输出保存到 Amazon Simple Storage Service (Amazon S3) 或 HDFS。请勿使用 Beeline 或 SQL Workbench/J 查看查询结果。
重启 Hive
如果您在 hive-site.xml 或 hive-env.sh 中修改 Hive 属性,您可能需要在更新的设置生效前重启 Hive。重新启动 Hive-server 2 会影响集群上正在运行的查询。最佳实践是在没有查询运行时或在计划的维护时段内重新启动进程。
用于重新启动 Hive 进程的命令因 Amazon EMR 发行版本而异。有关更多信息,请参阅如何在 Amazon EMR 中重启服务?
对于 Amazon EMR 发行版 5.30 和更高版本或 6.0 和更高版本:
1. 使用 SSH 连接到主节点。
2. 重启元存储:
sudo systemctl stop hive-hcatalog-server sudo systemctl start hive-hcatalog-server sudo systemctl status hive-hcatalog-server
3. 重启 hive-server 2:
sudo systemctl stop hive-server2 sudo systemctl start hive-server2 sudo systemctl status hive-server2
对于 Amazon EMR 发行版 4.7.0 到 5.29:
1. 使用 SSH 连接到主节点。
2. 重启元存储:
sudo stop hive-hcatalog-server sudo start hive-hcatalog-server sudo status hive-hcatalog-server
**注意:**请勿尝试使用 sudo restart hive-hcatalog-server 命令重启元存储。
3. 重启 hive-server2:
sudo stop hive-server2 sudo start hive-server2 sudo status hive-server2
对于 Amazon EMR 发行版本 4.0.0 至 4.6:
1. 使用 SSH 连接到主节点。
2. 重启元存储:
sudo stop hive-metastore sudo start hive-metastore sudo status hive-metastore
3. 重启 hive-server2:
sudo stop hive-server2 sudo start hive-server2 sudo status hive-server2
相关信息
相关内容
- AWS 官方已更新 3 年前
- AWS 官方已更新 2 年前