FusionInsight HD Spark组件堆外内存超限导致JDBCServer作业失败

发布时间:  2016-09-18 浏览次数:  460 下载次数:  0
问题描述

JDBCServerSQL任务失败,通过现场的日志我们看到是Spark任务的一个task重试4次都失败了,原因是shuffle文件找不到:

2016-05-05 05:03:10,236 [sdp_Worker-22] ERROR - LAJob4CorporateCustomer SQLException:org.apache.spark.SparkException: Job aborted due to stage failure: Task 7 in stage 8581.1 failed 4 times, most recent failure: Lost task 7.3 in stage 8581.1 (TID 663139, pdccjfsdpapp072): java.io.FileNotFoundException: /srv/BigData/hadoop/data1/nm/localdir/usercache/spark/appcache/application_1460839308193_132102/blockmgr-36b59ce5-2eac-4a6e-85f0-39f5a8ca6686/16/shuffle_6293_37_0.index (No such file or directory)

        at java.io.FileOutputStream.open(Native Method)

        at java.io.FileOutputStream.<init>(FileOutputStream.java:221)

        at java.io.FileOutputStream.<init>(FileOutputStream.java:171)

        at org.apache.spark.shuffle.IndexShuffleBlockManager.writeIndexFile(IndexShuffleBlockManager.scala:85)

        at org.apache.spark.shuffle.sort.SortShuffleWriter.write(SortShuffleWriter.scala:69)

        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:68)

        at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:41)

        at org.apache.spark.scheduler.Task.run(Task.scala:56)

        at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:197)

        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

        at java.lang.Thread.run(Thread.java:745)

处理过程

上述日志是客户应用捕获服务端的异常,所以真正的异常是SparkJDBCServer服务端产生的,查看对应时间段得SparkJDBCServer服务端日志,发现存在大量的Executor lost的异常:

2016-05-05 05:03:23,863 | ERROR | [sparkDriver-akka.actor.default-dispatcher-15] | Lost executor 281 on pdccjfsdpsvr025: remote Akka client disassociated | org.apache.spark.Logging$class.logError(Logging.scala:75)

2016-05-05 05:03:25,342 | ERROR | [sparkDriver-akka.actor.default-dispatcher-20] | Lost executor 290 on pdccjfsdpsvr024: remote Akka client disassociated | org.apache.spark.Logging$class.logError(Logging.scala:75)

2016-05-05 05:03:32,706 | ERROR | [sparkDriver-akka.actor.default-dispatcher-4] | Lost executor 292 on pdccjfsdpapp072: remote Akka client disassociated | org.apache.spark.Logging$class.logError(Logging.scala:75)

2016-05-05 05:03:44,804 | ERROR | [sparkDriver-akka.actor.default-dispatcher-16] | Lost executor 291 on pdccjfsdpapp075: remote Akka client disassociated | org.apache.spark.Logging$class.logError(Logging.scala:75)

2016-05-05 05:04:35,143 | ERROR | [sparkDriver-akka.actor.default-dispatcher-4] | Lost executor 288 on pdccjfsdpsvr025: remote Akka client disassociated | org.apache.spark.Logging$class.logError(Logging.scala:75)

Executor lost的原因通过查看NodeManager日志得到如下信息:

2016-05-05 05:02:46,748 | WARN  | Container Monitor | Container [pid=48832,containerID=container_1460839308193_132102_01_016154] is running beyond physical memory limits. Current usage: 22.1 GB of 22 GB physical memory used; 23.0 GB of 55 GB virtual memory used. Killing container.

Executor因为物理内存超限被NodeManager的资源监控线程杀死了,同时清除了该Executor的本地磁盘数据,所以才会有task需要从该Executor获取shuffle数据时出现文件找不到导致最终任务失败的情况。

根因

YarnHadoop的资源管理框架,对其调度的所有container都会监控其内存使用量,如果内存超限会将container杀死,以保证整个服务资源可控。

那么container为什么会内存超限呢?

Spark任务的Containerjava进程内存使用量基本有jvm heap值确定,通过GC参数保证heap使用内存在一个恒定范围内。但是java进程除了heap内存还会占用堆外内存(堆就是heap),通常是java进程依赖的底层库所消耗的内存。

Spark任务做Shuffle时每个ReduceTaskMapTask都会建立netty链接来获取数据,netty链接会占用堆外内存。到底一个任务会建立多少链接由任务数据量和数据分布来决定。当任务处理数据量大、数据分布随机的情况下,Shuffle时需要占用的堆外内存会相对较高。

解决方法:

增大配置参数spark.yarn.executor.memoryOverhead的值,默认为执行器内存的10%,单位为MB

解决方案

调整SparkJDBCServer服务的spark.yarn.executor. memoryOverhead参数值,建议当前调整为51205GB

由于C30版本SparkJDBCServer服务的该参数未开发,所以在界面上无法修改,需要通过修改后台配置文件公开该参数然后再修改,具体步骤如下:

步骤 1     使用PUTTYroot用户登录FI OMS服务器,用 su - omm 切换到omm用户。

步骤 2     切换目录(具体版本号已实际环境为准):

cd /opt/huawei/Bigdata/om-0.0.1/etc/components/FusionInsight_V100R002C30SPC60X/Spark/

步骤 3     vi 编辑configurations.xml配置文件,搜索“JDBCServer”配置区域

步骤 4     再搜索“spark-defaults.conf”配置区域

步骤 5    增加spark.yarn.executor.memoryOverhead配置项。


<property type="basic" scope="all" classification="Tuning">


                    <name>spark.yarn.executor.memoryOverhead</name>


                    <value vType="string">5120</value>


                </property>


                          步骤 6     保存退出vi 编辑。


                          步骤 7     重启 controller


/opt/huawei/Bigdata/om-0.0.1/sbin/restart-controller.sh


                          步骤 8     执行完命令后连续按回车键退出命令。


                          步骤 9     等待5min后进行后续操作。


                          步骤 10     打开FI WebUI,选择“Services > Spark > More Actions”,单击“Synchronize configuration”,弹出的提示框勾选重启选项。


                          步骤 11     登陆JDBCServer所在服务器检查配置是否同步生效。


cd /opt/huawei/Bigdata/etc/1_11_JDBCServer


vi spark-defaults.conf


END