更改了hive的启动配置,发现hive启动的控制台页面,出现很多日志信息,而改动之前这些日志都是不可见的。初步怀疑是slf4j的实现类加载异常。
分析hive的加载的slf4j实现类- 异常的slf4j 加载的class是Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/opt/apps/ecm/service/hive/3.1.2-hadoop3.1-1.3.3/package/apache-hive-3.1.2-hadoop3.1-1.3.3-bin/lib/log4j-slf4j-impl-2.17.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/opt/apps/ecm/service/hadoop/3.2.1-1.2.1/package/hadoop-3.2.1-1.2.1/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.slf4j.impl.Log4jLoggerFactory]
- 正常的slf4j加载的实现类是:org.apache.logging.slf4j.Log4jLoggerFactory
SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/opt/apps/ecm/service/hive/3.1.2-hadoop3.1-1.3.3/package/apache-hive-3.1.2-hadoop3.1-1.3.3-bin/lib/log4j-slf4j-impl-2.17.0.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/opt/apps/ecm/service/hadoop/3.2.1-1.2.1/package/hadoop-3.2.1-1.2.1/share/hadoop/common/lib/slf4j-log4j12-1.7.25.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [org.apache.logging.slf4j.Log4jLoggerFactory]
可以看到两个实现类加载不一样,导致日志打印异常。
查看实现类是被谁加载的在hive的脚本中,更改HADOOP_OPTS,增加 HADOOP_OPTS = “$HADOOP_OPTS -verbose:class”,这样jvm中启动过程中,就会记录class被哪个jar加载的。配置完成之后,重新启动hivecli。
查看slf4j类加载过程
正常的slf4j实现类加载过程,如下所示,可以看到这个是被hive所依赖的包,所以能够正常加载日志。
[Loaded org.apache.logging.slf4j.Log4jLoggerFactory from file:/opt/apps/ecm/service/hive/3.1.2-hadoop3.1-1.3.3/package/apache-hive-3.1.2-hadoop3.1-1.3.3-bin/lib/log4j-slf4j-impl-2.17.0.jar]
异常的hive的slf4j实现类加载过程
[Loaded org.slf4j.impl.Log4jLoggerFactory from /opt/apps/ecm/service/taihaodoctor/5.0.0-1.0.0/package/taihaodoctor-5.0.0-1.0.0/emr-agent/btrace-libs/mr/boot/agent-1.0.jar]
因为这个是新加的btrace-libs类,导致该类提前加载了非hive的使用log4j实现类,导致hive日志异常。
解决方案StaticLoggerBinder的获取实现类的变量是static(static final String loggerFactoryClassStr = Log4jLoggerFactory.class.getName()),因此在类首次加载的时候就会创建这个变量。如果要想获取正确的实现类,也就是获取到正确的StaticLoggerBinder类,那么就要让想要的StaticLoggerBinder首先被加载到。那么如何做到呢?
答案是:更改类加载顺序,让hive依赖的StaticLoggerBinder类先加载。那么就需要更改classpath的方式。另外也要防止一些fat jar中存在StaticLoggerBinder导致也会被先加载
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)