Impala Catalogd启动报错NoClassDefFoundError: org.apache.hadoop.fs.FileSystem

开端

今天在部署Impala时遇到一个NoClassDefFoundError的错误,本以为只是CLASSPATH的小问题,没想到调查了一天……

事情是这样的,编译Impala生成RPM,部署到另一台机器上后,statestored能正常启动,catalogd启动报错:

I0411 13:38:14.642241 113789 init.cc:599] OS distribution: CentOS Linux 8 (Core)
OS version: Linux version 5.4.243-1.el7.elrepo.x86_64 (mockbuild@Build64R7) (gcc version 9.3.1 20200408 (Red Hat 9.3.1-2) (GCC)) #1 SMP Tue May 16 10:43:45 EDT 2023
Clock: clocksource: 'tsc', clockid_t: CLOCK_MONOTONIC
I0411 13:38:14.642261 113789 init.cc:600] Process CGroup Info: memory.limit_in_bytes=9223372036854771712
I0411 13:38:14.642583 113789 init.cc:601] Process ID: 113789
I0411 13:38:14.642594 113789 init.cc:602] Default AES cipher mode for spill-to-disk: AES-GCM
I0411 13:38:14.746702 113789 init.cc:440] Using Java weigher sizeof
I0411 13:38:15.480756 113789 webserver.cc:395] Starting webserver on 0.0.0.0:25020
I0411 13:38:15.480811 113789 webserver.cc:411] Document root: /opt/impala
I0411 13:38:15.481134 113789 webserver.cc:548] Webserver started
I0411 13:38:15.609732 113789 jni-util.cc:302] java.lang.NoClassDefFoundError: org.apache.hadoop.fs.FileSystemat org.apache.hadoop.hive.conf.valcoersion.JavaIOTmpdirVariableCoercion.<clinit>(JavaIOTmpdirVariableCoercion.java:37)at org.apache.hadoop.hive.conf.SystemVariables.<clinit>(SystemVariables.java:37)at org.apache.hadoop.hive.conf.HiveConf$ConfVars.<init>(HiveConf.java:5736)at org.apache.hadoop.hive.conf.HiveConf$ConfVars.<init>(HiveConf.java:5717)at org.apache.hadoop.hive.conf.HiveConf$ConfVars.<clinit>(HiveConf.java:536)at org.apache.hadoop.hive.conf.HiveConf.<clinit>(HiveConf.java:256)at org.apache.impala.service.JniCatalog.<clinit>(JniCatalog.java:135)
I0411 13:38:15.609787 113789 status.cc:129] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem@          0x10a02f4@          0x1c21104@          0x1036151@           0xfd433d@           0xf5a43e@           0xe5b774@     0x7f81d2bf66a3@           0xf05c2e
F0411 13:38:15.611681 113789 catalog.cc:86] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem
. Impalad exiting.
Minidump with no thread info available.
Wrote minidump to /var/log/impala-minidumps/catalogd/86355b1b-4d2c-4195-61ac0d9e-68059041.dmp

catalogd.ERROR也没有更多有用的信息:

Log file created at: 2024/04/11 13:38:14
Running on machine: ccycloud-3.quanlong.root.comops.site
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
E0411 13:38:14.627285 113789 logging.cc:256] stderr will be logged to this file.
log4j:WARN No appenders could be found for logger (org.apache.hadoop.conf.Configuration).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
F0411 13:38:15.611681 113789 catalog.cc:86] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem
. Impalad exiting.
*** Check failure stack trace: ***@          0x391054d@          0x3912484@          0x390ff2c@          0x39129a9@          0x103625b@           0xfd433d@           0xf5a43e@           0xe5b774@     0x7f81d2bf66a3@           0xf05c2e
Minidump with no thread info available.
Wrote minidump to /var/log/impala-minidumps/catalogd/86355b1b-4d2c-4195-61ac0d9e-68059041.dmp

报错是 “NoClassDefFoundError: org.apache.hadoop.fs.FileSystem”, 报的是 NoClassDefFoundError 而不是常见的 ClassNotFoundException。一开始没在意,先排查CLASSPATH的问题。

由于之前遇到过 IMPALA-12979 的问题,CLASSPATH里没有用通配符 *,而是写明了所有目录和jar包的绝对路径,这个没问题。

FileSystem这个类是在 hadoop-common 包中提供的,在CLASSPATH中确认了有这个包。为了进一步确认它被使用了,在环境变量 JAVA_TOOL_OPTIONS 里加 -verbose:class,再次启动 catalogd,能在日志里看到 ClassLoader 加载这个类的日志:

[Loaded org.apache.hadoop.fs.FileSystem from file:/opt/impala/lib/jars/hadoop-common-3.1.1.7.2.18.0-369.jar]

这让我陷入了沉思……

转机

常用的debug方法就是在好坏两个重现之间找差异。同一台机器上还有CM部署的Impala,之前的配置就是从CM部署的配置复制过去的,所以配置内容是一样的。我把CDP parcel里的impalad可执行文件和jar包全都替换成我先前部署的版本,发现CM竟然可以启动catalogd! 这说明可执行文件和jar包没问题,可能还是CLASSPATH的问题。

于是我用CM的CLASSPATH,在前面加上 /opt/impala/conf(即我手动部署的配置目录),启动手动部署的catalogd,发现还是报一样的错。再度陷入沉思……

于是开始各种查 NoClassDefFoundError 的报错机制,发现它和 ClassNotFoundException 还是有区别的。ClassNotFoundException 是这个类在CLASSPATH里真的找不到,ClassLoader报的错。NoClassDefFoundError 可能是这个类找到了,但在加载的时候初始化 static 成员时报错,导致这个类无法被使用。网上很多只说了CLASSPATH有问题,这个回答才比较全面:https://stackoverflow.com/a/2213496/5996453

看报错堆栈,确实是在初始化static成员出的错:

I0411 13:38:15.609732 113789 jni-util.cc:302] java.lang.NoClassDefFoundError: org.apache.hadoop.fs.FileSystemat org.apache.hadoop.hive.conf.valcoersion.JavaIOTmpdirVariableCoercion.<clinit>(JavaIOTmpdirVariableCoercion.java:37)

对应的 JavaIOTmpdirVariableCoercion.java 代码是:

 34 public class JavaIOTmpdirVariableCoercion extends VariableCoercion {35   private static final Logger LOG = LoggerFactory.getLogger(JavaIOTmpdirVariableCoercion.class);36   private static final String NAME = "system:java.io.tmpdir";37   private static final FileSystem LOCAL_FILE_SYSTEM = new LocalFileSystem();

至于是初始化 LOCAL_FILE_SYSTEM 时的 new LocalFileSystem() 失败了,还是初始化 FileSystem 的静态成员失败了,还不得而知。奇怪的是 catalogd 日志里并没有其它的报错,难道是 JNI 相关的代码把报错忽略了?

又过了一下FileSystem.java的代码,可能初始化失败的static成员倒是有几个:

    public static final Logger LOG = LoggerFactory.getLogger(FileSystem.class);private static final Logger LOGGER =LoggerFactory.getLogger(FileSystem.class);/** FileSystem cache. */static final Cache CACHE = new Cache(new Configuration());     

但是没有日志真不好往下查,于是我又开始玩弄好坏两个重现,尽可能让它们相近。机缘巧合,发现完全用CM的CLASSPATH就没问题,但哪怕是前面加上 /opt/impala/conf 都不行!所以问题可能还是在配置文件上。

真相浮出水面

逐个对比core-site.xml、hdfs-site.xml、hive-site.xml,只有细微的差别(中途我用CM加了些DataNode节点导致的)。把它们的内容都改成CM部署的一样的内容,发现还是报错。

又一次机缘巧合,想到可能是权限的问题,于是检查了一下,发现我启动catalogd用的用户名(“impala”),确实没法读我部署的配置文件!

这是我当时用的复制指令:

# cp /var/run/cloudera-scm-agent/process/46-impala-CATALOGSERVER/hadoop-conf/* /opt/impala/conf

这是源文件的权限:

# ls -l /var/run/cloudera-scm-agent/process/46-impala-CATALOGSERVER/hadoop-conf/
total 16
-rw-r----- 1 impala impala 5331 Apr 11 01:49 core-site.xml
-rw-r----- 1 impala impala 2455 Apr 11 01:49 hdfs-site.xml
-rw-r----- 1 impala impala  315 Apr 11 01:49 ssl-client.xml

这是目标文件的权限:

# ls -l /opt/impala/conf/core-site.xml
-rw-r----- 1 root root 5331 Apr 12 03:02 /opt/impala/conf/core-site.xml

因为我是用root用户复制的,文件的owner变成了root,而文件的权限在 other 部分是 0,这就导致 “impala” 用户名无法读取这个文件!

把所有配置文件都加上 other 的读权限后,问题就解决了

# chmod o+r /opt/impala/conf/*
# ls -l /opt/impala/conf/core-site.xml
-rw-r--r-- 1 root root 5331 Apr 12 03:02 /opt/impala/conf/core-site.xml

没想到这个 NoClassDefFoundError 重误的原因真不是CLASSPATH有问题,而是匹配文件的问题。

归因

还有一些问题没弄清楚:

  • 为什么没有抛读不了core-site.xml文件的报错?
  • core-site.xml读不了是怎么导致NoClassDefFoundError的?具体是FileSystem还是其它哪个类的static成员初始化出问题了?

回到本地的 impala 开发环境,我重现了问题,不光是core-site.xml读不了时会出这个问题,如果core-site.xml里有语法错误(即不是一个合法的XML文件)也会出这个问题。

有意思的是 catalogd.ERROR 居然在 NoClassDefFoundError 前有具体的报错,比如core-site.xml没权限读时:

24/04/11 20:42:52 ERROR conf.Configuration: error parsing conf core-site.xml
java.io.FileNotFoundException: /home/quanlong/workspace/Impala/fe/src/test/resources/core-site.xml (Permission denied)at java.io.FileInputStream.open0(Native Method)at java.io.FileInputStream.open(FileInputStream.java:195)at java.io.FileInputStream.<init>(FileInputStream.java:138)at java.io.FileInputStream.<init>(FileInputStream.java:93)at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)at org.apache.hadoop.conf.Configuration.parse(Configuration.java:3023)at org.apache.hadoop.conf.Configuration.getStreamReader(Configuration.java:3119)at org.apache.hadoop.conf.Configuration.loadResource(Configuration.java:3077)at org.apache.hadoop.conf.Configuration.loadResources(Configuration.java:3050)at org.apache.hadoop.conf.Configuration.loadProps(Configuration.java:2928)at org.apache.hadoop.conf.Configuration.getProps(Configuration.java:2910)at org.apache.hadoop.conf.Configuration.get(Configuration.java:1264)at org.apache.hadoop.conf.Configuration.getTrimmed(Configuration.java:1318)at org.apache.hadoop.conf.Configuration.getInt(Configuration.java:1543)at org.apache.hadoop.fs.FileSystem$Cache.<init>(FileSystem.java:3495)at org.apache.hadoop.fs.FileSystem.<clinit>(FileSystem.java:194)
24/04/11 20:42:52 INFO util.JvmPauseMonitor: Starting JVM pause monitor
24/04/11 20:42:52 INFO conf.HiveConf: Found configuration file file:/home/quanlong/workspace/Impala/fe/src/test/resources/hive-site.xml
F0411 20:42:52.422523 16481 catalog.cc:86] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem
. Impalad exiting.
*** Check failure stack trace: ***@          0x3982bbd  google::LogMessage::Fail()@          0x3984af4  google::LogMessage::SendToLog()@          0x398259c  google::LogMessage::Flush()  @          0x3985019  google::LogMessageFatal::~LogMessageFatal()@          0x103c3bd  impala::Catalog::Catalog()@           0xffa5b9  impala::CatalogServer::Start()@           0xf3d8d7  CatalogdMain()@           0xf3c25f  main@     0x7f7f21435c87  __libc_start_main@           0xf3c09a  _start
Minidump with no thread info available.
Wrote minidump to /home/quanlong/workspace/Impala/logs/cluster/minidumps/catalogd/f13bee4f-b6fc-4a6a-392f1782-32ed878f.dmp

从第一个报错堆栈能清晰地看到,初始化 FileSystem 的 static 成员 CACHE 时,需要创建一个 Configuration 对象,这一步因为读不了 core-site.xml 而出错了。从而也就产生了 “NoClassDefFoundError: org.apache.hadoop.fs.FileSystem” 的报错。这回答了第二个问题。

为什么第一个报错没在部署的远程机器上打印出来?

  • 难道是RELEASE build和DEBUG build的区别?我本地是DEBUG build,所以默认有打印C++的堆栈。重新编译成 RELEASE build试了一下,发现日志也是有这个报错的。
  • 难道是系统差异导致的?远程机器是Redhat 8.9,本地开始环境是Ubuntu 18.04。于是试了下在Redhat 8.9里搭建impala开发环境并重现问题,发现日志也是有第一个报错的。

后来突然意识到,第一个报错FileNotFoundException的日志格式和第二个报错NoClassDefFoundError的日志格式是不同的:

24/04/11 20:42:52 ERROR conf.Configuration: error parsing conf core-site.xml
java.io.FileNotFoundException: ...
F0411 20:42:52.422523 16481 catalog.cc:86] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem

第二个报错的格式是glog配置的格式,而第一个的格式在impala日志中很少见,没有源码文件名和行号,也没有线程id。回看部署机器上的 catalogd.ERROR,开头其实有段 log4j 的warning:

log4j:WARN No appenders could be found for logger (org.apache.hadoop.conf.Configuration).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
F0411 13:38:15.611681 113789 catalog.cc:86] NoClassDefFoundError: org.apache.hadoop.fs.FileSystem

这应该是第一个报错想打印却打印不出来的warning!然后我发现,开发环境的配置文件里是有 log4j.properties 的,但部署环境的配置文件里没有。原来这就是真正的报错没打印的原因!在部署的远程机器里补上 log4j.properties 后,确实就能看到第一个报错的日志了。提了 IMPALA-12999 修复这个问题。

Impala的日志打印很特别,因为代码里即有C++又有Java的。C++代码使用glog打印日志,Java代码使用log4j打印日志,然后通过Impala实现的GlogAppender把 log4j 的日志导到 glog 里去打印。而 GlogAppender 的初始化是在 JniCatalog 的构造函数里的,这个发生在初始化 static 成员之后。因此第一个报错抛出来时,log4j还没被重定向到 glog 里,只是打印到了 stderr,从而出现在了 catalogd.ERROR(但不在catalogd.INFO)里。关于这部分代码的实现,之前梳理过一篇文章:Impala的log4j和glog配置

总结

许多事情回过头看都很简单,不过是 “当局者迷,旁观者清”。作为 “当局者”,一定要发散思维,不要在一条路上死磕,比如坚信 NoClassDefFoundError 只能是 CLASSPATH 有问题导致的,那还要浪费很多时间。

知识点:

  • Impala部署时也需要log4j.properties,以正常打印初始化时的Java日志。等log4j被重定向到glog后,这个配置就没用了。
  • ClassNotFoundException 是 ClassLoader 无法在 CLASSPATH 中找到某个类,经常是编译时和运行时的CLASSPATH不一致导致的。
  • NoClassDefFoundError 可能由 ClassNotFoundException 导致,也可能由其它原因如 static 成员初始化失败导致。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/811337.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

二分法查找左右边界(含代码模板)

问题1&#xff1a;使用mid left(right-left)/2 或者 mid (leftright)/2,两者计算结果相同吗&#xff1f; 在大多数情况下是等价的。 mid left (right - left) / 2&#xff1a;先计算了区间长度&#xff0c;然后再除以2。 这种方式可以避免整数溢出问题&#xff0c;因为它…

探索Java中的栈:Stack与Deque(ArrayDeque和LinkedList)

文章目录 1. 栈&#xff08;Stack&#xff09;1.1 定义方式1.2 特点1.3 栈的层次结构 2. 双端队列&#xff08;Deque&#xff09;2.1 定义方式及继承关系2.2 特点&#xff1a;2.3 ArrayDeque2.4 LinkedList2.5 Deque 的各种方法2.6 如何选择ArrayDeque和LinkedList 3. 如何选择…

冶炼金属(蓝桥杯)

文章目录 冶炼金属题目描述二分查找难点解释 冶炼金属 题目描述 小蓝有一个神奇的炉子用于将普通金属 O冶炼成为一种特殊金属 X。这个炉子有一个称作转换率的属性 V&#xff0c;V 是一个正整数&#xff0c;这意味着消耗 V个普通金属 O 恰好可以冶炼出一个特殊金属 X&#xff…

【稳定检索|投稿优惠】2024年生物学与智能计算国际会议 (ICBIC 2024)

2024年生物学与智能计算国际会议 (ICBIC 2024) 2024 International Conference on Biology and Intelligent Computing 【会议简介】 2024年生物学与智能计算国际会议即将在上海召开。本次会议旨在汇聚生物学与智能计算领域的专家学者&#xff0c;共同探讨两者交叉融合的前沿…

【Linux】网络基础(一)

文章目录 一、计算机网络背景1. 网络发展2. 认识“协议” 二、网络协议初识1. 协议分层2. OSI七层模型3. TCP/IP五层&#xff08;或四层&#xff09;模型 三、网络传输基本流程1. 同局域网的两台主机通信数据包封装和分用封装分用 2. 跨网络的两台主机通信 四、网络中的地址管理…

【webrtc】源码下载与编译

目录 下载 下依赖 内存需求 &#xff01;&#xff01; 参考文章 &#xff1a; 下载 (1) windows ,centos上都会报错 &#xff08;2&#xff09; ubuntu A : 在git上设置代理 B fetch通过 ubuntu的界面 proxy设置了代理 这将会拉取webRTC源码&#xff0c;且额外加了a…

ssm043基于JavaEE的龙腾公司员工信息管理系统的设计与实现+jsp

龙腾公司员工信息管理系统设计与实现 摘 要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本龙腾公司员工信息管理系统就是在这样的大环境下诞生&#xff0c;其可…

C++数据结构与算法——动态规划打家劫舍系列

C第二阶段——数据结构和算法&#xff0c;之前学过一点点数据结构&#xff0c;当时是基于Python来学习的&#xff0c;现在基于C查漏补缺&#xff0c;尤其是树的部分。这一部分计划一个月&#xff0c;主要利用代码随想录来学习&#xff0c;刷题使用力扣网站&#xff0c;不定时更…

千视电子携NDI 6前沿技术,亮相北京CCBN展呈现轻量化媒体解决方案

千视携NDI 6技术闪耀2024 CCBN展会&#xff0c;呈现轻量化媒体解决方案 2024年4月24日至26日&#xff0c;北京首钢会展中心将举办第三十届中国国际广播电视网络技术展览会&#xff08;CCBN2024&#xff09;。这是中国广播电视行业的一项重要盛会&#xff0c;将有国内外超600家…

kubectl_入门_Pod配置以及生命周期

Pod配置以及生命周期 1. Pod结构定义 每个pod中都可以包含一个或多个容器&#xff0c;这些容器可以分为两类 用户程序所在的容器&#xff0c;数量可多可少Pause容器&#xff0c;这是每个Pod都会有的一个根容器&#xff0c;它的作用有两个 可以以它为根据&#xff0c;评估整个…

异地两分部子网重复,如何远程更改其中一个分部子网信息

环境: 分部1:子网192.168.1.0/24 分部2:子网192.168.1.0/24 问题描述: 异地两分部子网重复,如何远程更改其中一个分部子网,原本没有问题目前要与总部建ipsec提示冲突无法都建立隧道 解决方案: 先G一下,看看有啥建议 在两个异地分部网络中,如果发现有子网地址出现…

java 解析 xml 字符串转换为实体,实体转换为 xml 字符串

java 解析 xml 字符串转换为实体&#xff0c;实体转换为 xml 字符串 1. XmlCommonUtil工具类代码如下&#xff1a; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller;/*** XmlCommonUtil类用于XML字符串和对象之间…

从零开始,如何成功进入IT行业?

0基础如何进入IT行业&#xff1f; 简介&#xff1a;对于没有任何相关背景知识的人来说&#xff0c;如何才能成功进入IT行业&#xff1f;是否有一些特定的方法或技巧可以帮助他们实现这一目标&#xff1f; 在当今数字化时代&#xff0c;IT行业无疑是一个充满活力和机遇的领域。…

Linux服务器疑似被入侵

随着开源产品的越来越盛行&#xff0c;作为一个Linux运维工程师&#xff0c;能够清晰地鉴别异常机器是否已经被入侵了显得至关重要&#xff0c;个人结合自己的工作经历&#xff0c;整理了几种常见的机器被黑情况供参考。 背景信息&#xff1a;以下情况是在CentOS 6.9的系统中…

Leetcode 56. 合并区间和Leetcode 240. 搜索二维矩阵 II

文章目录 Leetcode 56. 合并区间题目描述C语言题解和思路解题思路 Leetcode 240. 搜索二维矩阵 II题目描述C语言题解和思路解题思路 Leetcode 56. 合并区间 题目描述 以数组 intervals 表示若干个区间的集合&#xff0c;其中单个区间为 intervals[i] [starti, endi] 。请你合…

mac上如何安装python3

mac上如何安装python3&#xff1f; 安装homebrew 在终端执行命令 /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)" 执行完成后&#xff0c;homebrew和pip等工具就自动安装好了。 接下来安装python3.在终端…

C++生成随机数游戏

// 添加随机种子&#xff0c;作用&#xff1a;利用当前系统时间生成随机数&#xff0c;防止每次随机数都一样 srand((unsigned int)time(NULL)); #include <stdio.h> #include <windows.h> #include <iostream> #include <ctime> using namespace std;…

鸿蒙OS开发实例:【Native C++】

介绍 本篇Codelab主要介绍如何使用DevEco Studio创建一个Native C应用。应用采用Native C模板&#xff0c;实现使用NAPI调用C标准库的功能。使用C标准库hypot接口计算两个给定数平方和的平方根。在输入框中输入两个数字&#xff0c;点击计算结果按钮显示计算后的数值。 相关概…

Input Event Daemon:增强Linux输入设备的交互体验

在Linux系统中&#xff0c;设备之间的交互常常需要一些后台进程来监控并响应不同的输入事件&#xff0c;例如键盘按键、鼠标点击或系统唤醒信号。Input Event Daemon&#xff08;简称IED&#xff09;是一个用于Linux的后台服务程序&#xff0c;用以监听来自输入设备的事件&…

lanqiao.602 迷宫

题目&#xff1a; 代码&#xff1a; #include<iostream> #include<cstring> #include<algorithm> #include<queue> using namespace std; char mp[31][51]; //稍微开大一点 char k[4]{D,L,R,U}; //按字典序记录路径 int dirx[]{1,0,0,-1},d…