Hadoop无法加载自定义RackAwareness类,启动HDFS失败求助
问题描述
我已经在core-site.xml中配置了自定义的RackAwareness类,接着在hadoop-env.sh里添加了包含该类的ClassPath:
export HADOOP_CLASSPATH="/opt/modules/hadoop-2.7.2/lib/rack.jar"
执行hadoop classpath能看到这个路径,但启动HDFS后NameNode进程直接退出,日志报错如下:
java.lang.RuntimeException: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.learning.rackawareness.RackAwareness not found at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2227) at org.apache.hadoop.hdfs.server.blockmanagement.DatanodeManager.<init>(DatanodeManager.java:208) at org.apache.hadoop.hdfs.server.blockmanagement.BlockManager.<init>(BlockManager.java:268) at org.apache.hadoop.hdfs.server.namenode.FSNamesystem.<init>(FSNamesystem.java:737) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.initialize(SecondaryNameNode.java:246) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.<init>(SecondaryNameNode.java:192) at org.apache.hadoop.hdfs.server.namenode.SecondaryNameNode.main(SecondaryNameNode.java:671) Caused by: java.lang.RuntimeException: java.lang.ClassNotFoundException: Class com.learning.rackawareness.RackAwareness not found at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2195) at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2219) ... 6 more Caused by: java.lang.ClassNotFoundException: Class com.learning.rackawareness.RackAwareness not found at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:2101) at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:2193) ... 7 more
请问该怎么解决这个问题?
遇到这个问题我太熟悉了,大概率是类路径加载或者JAR包结构出了问题,给你几个排查和解决的步骤:
先确认JAR包的内部结构是否正确
你的自定义类全限定名是com.learning.rackawareness.RackAwareness,那JAR包里面必须有对应的目录层级:com/learning/rackawareness/RackAwareness.class。你可以用这个命令检查:jar tvf /opt/modules/hadoop-2.7.2/lib/rack.jar如果输出里找不到这个路径,说明你打包的时候目录结构错了,重新打包就行——打包时要基于类的根目录(也就是包含
com文件夹的那个目录)执行jar命令。别手动设置CLASSPATH,直接放默认加载目录
你在hadoop-env.sh里设置的HADOOP_CLASSPATH有时候会因为HDFS启动脚本的优先级问题没被读取到。最简单可靠的办法是把rack.jar直接放到${HADOOP_HOME}/share/hadoop/common/lib目录下,这个目录是Hadoop所有守护进程默认会扫描加载的类路径,放进去之后重启HDFS就行。检查core-site.xml里的类名配置有没有错
看你的报错日志里有个多余的>符号(Class >com.learning...),你得去core-site.xml里看看配置的topology.node.switch.mapping.impl参数值是不是多了这个符号,或者有没有拼写错误(比如大小写、包名写错)。这个配置必须和类的全限定名完全一致。验证类是否能被Hadoop类加载器识别
用Hadoop的命令行测试一下类能不能被找到:hadoop jar /opt/modules/hadoop-2.7.2/lib/rack.jar com.learning.rackawareness.RackAwareness如果这个命令报
main method not found,那说明类是能被加载的,问题出在HDFS启动时的配置;如果还是报ClassNotFoundException,那就是JAR包本身的问题,重新打包吧。重启时要彻底停掉所有进程
修改配置后,别只重启NameNode,要先把所有Hadoop进程都停掉(用stop-dfs.sh和stop-yarn.sh),然后再重新启动,这样新的类路径配置才能生效。
内容的提问来源于stack exchange,提问作者asdfjk

