前言
Hadoop YARN作为现代大数据平台的核心组件之一,其稳定性和性能至关重要。在部署和运维过程中,确保YARN组件,尤其是ResourceManager的顺利启动是日常工作中的一项基本任务。本文将详细介绍如何诊断并解决YARN启动时ResourceManager无法启动的问题。
问题描述
在启动Hadoop YARN时,通过jps命令检查进程,发现没有ResourceManager运行。这通常意味着YARN的ResourceManager启动失败。
日志分析
通过检查ResourceManager的日志文件hadoop-xxx-resourcemanager-.log,发现以下错误:
2024-01-15 11:46:14,440 ERROR org.apache.hadoop.yarn.server.resourcemanager.ResourceManager: Error starting ResourceManager
java.lang.ExceptionInInitializerError
at com.google.inject.internal.cglib.reflect.$FastClassEmitter.<init>(FastClassEmitter.java:67)
at org.apache.hadoop.yarn.webapp.WebApps$Builder.build(WebApps.java:417)
at org.apache.hadoop.yarn.webapp.WebApps$Builder.start(WebApps.java:465)
at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.startWepApp(ResourceManager.java:1389)
at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.serviceStart(ResourceManager.java:1498)
at org.apache.hadoop.service.AbstractService.start(AbstractService.java:194)
at org.apache.hadoop.yarn.server.resourcemanager.ResourceManager.main(ResourceManager.java:1700)
Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @4d7c417d
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354)
at java.base/java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297)
at java.base/java.lang.reflect.Method.checkCanSetAccessible(Method.java:199)
at java.base/java.lang.reflect.Method.setAccessible(Method.java:193)
at com.google.inject.internal.cglib.core.$ReflectUtils$2.run(ReflectUtils.java:56)
at java.base/java.security.AccessController.doPrivileged(AccessController.java:318)
at com.google.inject.internal.cglib.core.$ReflectUtils.<clinit>(ReflectUtils.java:46)
... 29 more
这个错误是由于JDK 8及更高版本中引入的模块化系统导致的。在这些版本中,默认情况下,不允许跨模块的某些反射访问,除非明确允许。
由于使用jdk17作为 hadoop java环境变量 故才引出此问题。
解决方案
修改yarn-env.sh文件:
编辑Hadoop配置文件yarn-env.sh,为JVM添加–add-opens参数以允许所需的反射访问。
export YARN_RESOURCEMANAGER_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED"
export YARN_NODEMANAGER_OPTS="--add-opens java.base/java.lang=ALL-UNNAMED"
清理Hadoop临时文件:
有时候,旧的临时文件可能会干扰Hadoop的正常启动。确保清理这些文件。
# 清理示例命令,具体路径根据实际环境而定
rm -rf /path/to/hadoop/tmp/*
重新启动Hadoop YARN:
在应用了上述更改并清理了临时文件后,重新启动YARN。
stop-yarn.sh
start-yarn.sh
验证ResourceManager是否成功启动:
使用jps命令或直接检查ResourceManager的日志文件,确认ResourceManager是否成功启动。
jps
可以观察日志查看启动情况 如果没有其他的报错的话 应该可以看到 ResourceManager
其他可能的问题
端口被占用
如果启动的端口被占用后,启动也会报错。结合日志观察是否是此问题
配置异常
需要正确的配置 ,才能保证启动成功 结合官方文档进行配置
官方文档: https://hadoop.apache.org/docs/r3.3.6/hadoop-project-dist/hadoop-common/SingleCluster.html#Setup_passphraseless_ssh
等等
总结
通过添加JVM参数–add-opens来允许必要的反射访问,可以解决因JDK 8及更高版本中的模块化限制导致的YARN ResourceManager启动失败问题。此外,定期清理Hadoop的临时文件也是保持系统健康运行的一个好习惯。
good day!!!