Driver端返回大量结果数据时出现内存不足错误

Driver端返回大量结果数据时出现内存不足错误

现象描述

利用JDBCServer应用,在客户端执行SQL语句。Driver异常退出,在JDBCServer日志中报错信息如下:

2015-11-24 18:29:33,393 ERROR [org.apache.spark.util.Utils] Uncaught exception in thread task-result-getter-3
java.lang.OutOfMemoryError: Java heap space
    at java.io.ObjectInputStream$HandleTable.grow(ObjectInputStream.java:3469)
    at java.io.ObjectInputStream$HandleTable.assign(ObjectInputStream.java:3275)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1674)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1993)
    at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1918)
    at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1801)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1351)
    at java.io.ObjectInputStream.readArray(ObjectInputStream.java:1707)
    at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1345)
    at java.io.ObjectInputStream.readObject(ObjectInputStream.java:371)
    at org.apache.spark.serializer.JavaDeserializationStream.readObject(JavaSerializer.scala:72)
    at org.apache.spark.serializer.JavaSerializerInstance.deserialize(JavaSerializer.scala:92)
    at org.apache.spark.scheduler.DirectTaskResult.value(TaskResult.scala:97)
    at org.apache.spark.scheduler.TaskResultGetter$$anon$2$$anonfun$run$1.apply$mcV$sp(TaskResultGetter.scala:60)
    at org.apache.spark.scheduler.TaskResultGetter$$anon$2$$anonfun$run$1.apply(TaskResultGetter.scala:51)
    at org.apache.spark.scheduler.TaskResultGetter$$anon$2$$anonfun$run$1.apply(TaskResultGetter.scala:51)
    at org.apache.spark.util.Utils$.logUncaughtExceptions(Utils.scala:1701)
    at org.apache.spark.scheduler.TaskResultGetter$$anon$2.run(TaskResultGetter.scala:50)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

客户端的错误信息如图1

图1 客户端报的错误


可能原因

分析日志可知,当运行“task-result-getter-3”线程时出现“Out-of-Memory”错误,即表示Driver端获取数据时出现内存不足,导致JDBCServer服务异常。

由于SQL查询的结果数据会返回Driver端,当查询结果数据较大时,会有大量数据返回到Driver。

返回数据的大小的上限由“spark.driver.maxResultSize”配置项控制,当返回结果数据量超过spark.driver.maxResultSize时,Job会抛出异常终止,但不会导致JDBCServer服务异常。在这个问题中,通过查看配置项可知,Driver端的内存为1GB,“spark.driver.maxResultSize”也是1GB,由于Driver进程中还有其他对象占用部分内存,所以在获取的数据量还没有达到“spark.driver.maxResultSize”时,Driver进程内存已经超过1GB从而发生内存溢出,导致JDBCServer服务异常退出。

定位思路

无。

处理步骤

出现该问题,可以通过两种方法修改:增加driver端的内存;控制返回driver端数据的大小。

  1. 根据具体的应用,修改driver端的内存大小,设置方法有如下两种:
    • 在CLASSPATH的“spark-defaults.conf”文件中添加spark.driver.memory 20g
    • 在启动Spark应用时,命令行中添加:–driver-memory 20g
  2. 为了减少Driver端出现out-of-memory的错误,您可以适当限制driver端的数据量使其在客户端即报错。 spark.driver.maxResultSize=256m 说明: 建议该配置项的值小于driver端的内存。
  3. 重新运行Spark应用,如上配置即生效。

参考信息

参考官网http://spark.apache.org/docs/latest/configuration.html,对“spark.driver.maxResultSize”配置项的介绍。

关注公众号“大模型全栈程序员”回复“小程序”获取1000个小程序打包源码。更多免费资源在http://www.gitweixin.com/?p=2627

发表评论

邮箱地址不会被公开。 必填项已用*标注