最近一周都在查项目的各种问题,由于对原有的一个MapReduce分析数据的项目进行重构,减少了运行时的使用资源,但是重构完成后,在Reduce端总是不定时地抛出JVM的相关错误,非常随机,没有发现有什么特殊的规律性。
问题在Reduce的控制台显示信息:
Exception from container-launch: org.apache.hadoop.util.Shell$ExitCodeException: /bin/bash: line 1: 12453 已放弃 /usr/java/jdk1.7.0_11//bin/java -Djava.net.preferIPv4Stack=true -Dhadoop.metrics.log.level=WARN -Xmx3072M -Djava.io.tmpdir=/home/data12/hdfsdir/nm-local-dir/usercache/supertool/appcache/application_1410771599055_15737/container_1410771599055_15737_01_000100/tmp -Dlog4j.configuration=container-log4j.properties -Dyarn.app.container.log.dir=/home/workspace/hadoop/logs/userlogs/application_1410771599055_15737/container_1410771599055_15737_01_000100 -Dyarn.app.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA org.apache.hadoop.mapred.YarnChild 192.168.7.87 29145 attempt_1410771599055_15737_r_000004_0 100 > /home/workspace/hadoop/logs/userlogs/application_1410771599055_15737/container_1410771599055_15737_01_000100/stdout 2> /home/workspace/hadoop/logs/userlogs/application_1410771599055_15737/container_1410771599055_15737_01_000100/stderr at org.apache.hadoop.util.Shell.runCommand(Shell.java:464) at org.apache.hadoop.util.Shell.run(Shell.java:379) at org.apache.hadoop.util.Shell$ShellCommandExecutor.execute(Shell.java:589) at org.apache.hadoop.yarn.server.nodemanager.DefaultContainerExecutor.launchContainer(DefaultContainerExecutor.java:195) at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:283) at org.apache.hadoop.yarn.server.nodemanager.containermanager.launcher.ContainerLaunch.call(ContainerLaunch.java:79) at java.util.concurrent.FutureTask$Sync.innerRun(FutureTask.java:334) at java.util.concurrent.FutureTask.run(FutureTask.java:166) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:722)
在System log中的信息为:
# # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x0000000000016996, pid=18611, tid=1097111872 # # JRE version: 7.0_11-b21 # Java VM: Java HotSpot(TM) 64-Bit Server VM (23.6-b04 mixed mode linux-amd64 compressed oops) # Problematic frame: # C 0x0000000000016996 [error occurred during error reporting (printing problematic frame), id 0xb] # Failed to write core dump. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again # # An error report file with more information is saved as: # /home/data9/hdfsdir/nm-local-dir/usercache/supertool/appcache/application_1410771599055_15737/container_1410771599055_15737_01_000099/hs_err_pid18611.log # # If you would like to submit a bug report, please visit: # http://bugreport.sun.com/bugreport/crash.jsp #
系统中提示的JVM dump文件并没有在那台Reduce端机器上被发现,由于Reducer会在任务执行完成后将所有文件夹及文件都清理掉,application文件夹都没有发现。
由于Java的安全性,出现内存错误也不会报上面的这种类型异常,一般是某个区域空间不足,比如Perm,Heap等。经过一轮排查,将问题锁定在Reduce端会调用的一段JNI代码上。关于JNI的基本使用,可以参考:http://brandnewuser.iteye.com/blog/2117182
将JNI的代码注释掉之后,果然问题不再重现。在重构该部分代码之前,系统并未产生过这种类型的错误,于是将调用JNI这段代码还原到以前的一个版本,发现错误仍然发生;考虑到重构前代码使用内存很大,测试时将Reducer端的Heap内存也提高到8G,同样不管用。
尝试加入-XCheck:jni=true参数,发现hadoop的压缩格式都会发生检查错误,比如SequenceFile以及Snappy压缩,程序无法进行,因此暂时还是关闭了这个参数。
同事开始对JNI使用的.so库进行多进程测试i执行,结果表明该库并不存在并发问题。
那么想办法将这个dump文件保存起来,避免无意中删除该文件,经过查找找到参数:
-Dmapreduce.task.files.preserve.failedtasks=true
参数表示保留失败的tasks相关文件,但是实际运行完成后也并没有保存,又经过查找,看到另外一个参数,设置该参数后,dump文件仍然被清除。
yarn.log-aggregation.retain-seconds=-1 保存汇聚日志时间,秒,超过会删除,-1表示不删除。 注意,设置的过小,将导致NN垃圾碎片。建议3-7天 = 7 * 86400 = 604800 yarn.nodemanager.log.retain-seconds=10800 保留用户日志的时间,秒。在日志汇聚功能关闭时生效。 建议7天
注:有篇文章讲Hadoop的所有使用参数,比较详细:http://segmentfault.com/blog/timger/1190000000709725
有同事说这个时yarn的参数,是否需要重新启动yarn框架(不需要重启整个map/reduce框架),果然在失败后拿到了core.dump文件!
高兴之余,C++高手用gdb对这个文件进行了详细的分析,并没有发现太多线索。
于是大家一起重新过了使用JNI的代码,果然发现了一个问题。我们在使用JNI时,将.so库打包到jar包中,在实际Reduce端运行时才会将该.so文件用文件流的方式写到当前/tmp文件夹下,这就意味着,加入多个Reduce同时运行该程序,就会导致该so文件重复写的可能。
为了验证是否这个原因导致的,我们在Reduce端开始运行时,ssh到那台机器上,用shell脚本循环重复地向该文件夹中复制so文件,该JVM错误稳定重现。(下图就是一个FAILED Reduce Task的部分截图)
仔细想了一下,为什么原来的代码中并没有出现该问题,因为原来的程序Reduce端占用比较大,并且Partition的哈希并不均匀,我们只能启动大概3个任务,出现错误的概率比较小,于是我们强制启动5个任务,果然发生了一个Reduce端出现了错误。
错误在Reduce端有3种类型:
- 已放弃;
- 段错误;
- 总线错误;
但原因都是一致的,在JNI执行调用时,库文件被莫名地替换掉了,导致无法找到该内存地址的数据(猜测),从而导致段错误等内存地址错误(SEGSEGV)的发生。
于是我们马上改代码,更改的思路,是在map/reduce任务中,Task的AttempID总是唯一的,于是考虑将每个任务的.so本地库文件进行了文件夹隔离,通过运行时的JobConf参数获得:
JobContext.TASK_ATTEMPT_ID(mapreduce.task.attempt.id)
于是,问题便顺利地解决再也不重现了,但需要在Reduce端执行完成后,将该文件夹的数据进行清理操作。可是如果任务是被Container kill或是自己Fail掉的,并不会得到清理,需要写脚本确保在没有任务执行时将集群中的文件夹清理。
相关推荐
管理员可以使用各种命令行工具和第三方监控工具来管理和维护Hadoop集群,包括监控日志级别(如WARN或INFO),以便及时发现和解决潜在问题。 Hadoop API的日志级别设置也很关键。WARN级别的日志只在发生错误时记录,...
Hive 是一个基于 Hadoop 的数据仓库工具,用于存储、查询和分析大规模数据。但是,在使用 Hive 过程中,经常会遇到一些常见错误,影响着整个项目的进度和效率。因此,本文将总结常见的 Hive 错误及解决方案,帮助...
在使用Hadoop集群的过程中,可能会遇到一系列的错误和问题,这些问题主要集中在集群的启动、在Master上运行示例以及在Windows环境下使用Eclipse运行程序时。以下是对这些常见错误的详细解析和解决策略: 1. **启动...
但是在使用 Hadoop 过程中,我们经常会遇到一些错误和问题,本文将为您提供一些常见的 Hadoop 故障解决方法。 一、Shuffle Error: Exceeded MAX_FAILED_UNIQUE_FETCHES; bailing-out 这个错误是由于系统默认的打开...
3. **存储**:通常情况下,输入和输出数据都会存储在一个文件系统中。 4. **任务管理**:框架负责调度任务、监控任务执行情况,并重新执行失败的任务。 为了提高效率,计算节点和存储节点通常是相同的,即 ...
首先,我们要理解Hadoop是Apache开源项目的一个组件,它是一个分布式文件系统(HDFS)和MapReduce计算框架的集合,广泛应用于大数据处理。Eclipse是一个流行的Java集成开发环境,通过安装特定插件,可以支持Hadoop...
7.1 使用图进行数据建模和解决问题 7.1.1 模拟图 7.1.2 最短路径算法 技术点52 找出两个用户间的最短距离 7.1.3 friends-of-friends(FoF) 技术点53 计算FoF 7.1.4 PageRank 技术点54 通过Web ...
每个在运行的文件、网络连接或套接字都会占用一个文件描述符。在Hadoop中,DataNode节点可能需要打开大量文件来存储和检索数据块,因此容易触发此限制。 解决方案: - **检查并增加文件描述符限制**:首先,登录...
Hadoop是一个分布式计算框架,用于处理和存储大量数据。当Hadoop在Red Hat操作系统上运行时,可能会遇到性能和兼容性问题,尤其是当它依赖于本地库时。这个问题通常出现在Hadoop的Java层与底层操作系统的交互过程中...
11. **Task执行与环境**:每个Task都在一个独立的JVM中运行,内存管理和参数设置直接影响任务性能。 12. **Shuffle/Reduce参数**:可以配置Shuffle和Reduce阶段的相关参数,如缓冲区大小、排序内存等,以优化性能。...
7. **故障排查与恢复**:介绍Hadoop系统中的错误类型,以及如何定位和解决问题,确保集群稳定运行。 通过这本书的源码,读者不仅可以学习到Hadoop的基本概念和原理,还能通过实际代码加深理解,从而在实践中运用...
例如,如果你有一个包含多个类库的项目,你可能需要将这些库的路径添加到classpath中,以便Java程序能够找到并加载所需的类。 2. 配置classpath 在Windows系统中,你可以通过编辑系统环境变量来设置classpath。例如...
Hadoop是一个开源的、能够存储和处理大规模数据集的软件框架。Hadoop 2.9.0版本中的mapred-default.xml文件包含了MapReduce作业的配置属性,这些属性定义了MapReduce作业执行过程中的各种行为和参数。下面我们来详细...
HDFS存放策略是将一个副本放在本地机架上的节点,一个副本放在同一机架上的另一个节点,最后一个副本放在不同机架上的一个节点,这样即便某一个机架出现问题,也不会影响到数据的可靠性和有效性。HDFS具有集群均衡...
Hadoop是Apache基金会的一个开源项目,主要用于大数据处理和分析。它基于Google的GFS(Google File System)和MapReduce计算模型,提供了一个分布式文件系统(HDFS)和分布式计算框架。在伪分布式环境中,Hadoop在单...
HBase提供了强一致性的读写操作,适用于实时分析和大数据实时应用。 在Java开发中,为了将这些组件整合在一起,你需要相关的jar包,例如包含Hive和HBase的API。这些API允许你在Scala程序中直接操作Hive和HBase,...
Kylin是Apache的一个顶级项目,它是一款为企业级大数据分析设计的开源在线分析处理(OLAP)系统,能够提供亚秒级别的查询速度。在CDH中部署Kylin,你需要先确保CDH环境中已经安装了HBase,因为Kylin依赖于HBase作为...
Java虚拟机(JVM)是Java程序运行的核心组件,它为Java代码提供了一个跨平台的运行环境。JVM解析.class文件,将字节码转换为机器码执行,并负责内存管理和垃圾回收。垃圾回收是JVM自动管理内存的过程,它识别并清理...
Hadoop 3.1.3是Hadoop的一个稳定版本,相比早期版本,它包含了许多性能优化、功能增强和错误修复。例如,它支持更高效的数据块复制策略、改进的资源调度器和更好的安全性特性。 JDK 8u212是Java开发和运行环境的...
Hadoop是一个开源的分布式计算框架,由Apache软件基金会维护,它允许处理和存储大规模数据集。Hadoop的核心组件包括Hadoop Distributed File System (HDFS)和MapReduce,前者提供了高容错性的数据存储,后者则实现了...