1、启动命令
${HBASE_HOME}/bin/hbase-daemon.sh start thrift2
2、异常情况
hbase-root-thrift2-hdfs-test07.yingzi.com.out异常日志:
Exception in thread "main" java.lang.AbstractMethodError: org.apache.hadoop.metrics2.sink.timeline.HadoopTimelineMetricsSink.init(Lorg/apache/commons/configuration/SubsetConfiguration;)V
at org.apache.hadoop.metrics2.impl.MetricsConfig.getPlugin(MetricsConfig.java:199)
at org.apache.hadoop.metrics2.impl.MetricsSystemImpl.newSink(MetricsSystemImpl.java:529)
at org.apache.hadoop.metrics2.impl.MetricsSystemImpl.configureSinks(MetricsSystemImpl.java:501)
at org.apache.hadoop.metrics2.impl.MetricsSystemImpl.configure(MetricsSystemImpl.java:480)
at org.apache.hadoop.metrics2.impl.MetricsSystemImpl.start(MetricsSystemImpl.java:189)
at org.apache.hadoop.metrics2.impl.MetricsSystemImpl.init(MetricsSystemImpl.java:164)
at org.apache.hadoop.metrics2.lib.DefaultMetricsSystem.init(DefaultMetricsSystem.java:54)
at org.apache.hadoop.metrics2.lib.DefaultMetricsSystem.initialize(DefaultMetricsSystem.java:50)
at org.apache.hadoop.hbase.metrics.BaseSourceImpl$DefaultMetricsSystemInitializer.init(BaseSourceImpl.java:51)
at org.apache.hadoop.hbase.metrics.BaseSourceImpl.<init>(BaseSourceImpl.java:112)
at org.apache.hadoop.hbase.metrics.ExceptionTrackingSourceImpl.<init>(ExceptionTrackingSourceImpl.java:44)
at org.apache.hadoop.hbase.thrift.MetricsThriftServerSourceImpl.<init>(MetricsThriftServerSourceImpl.java:59)
at org.apache.hadoop.hbase.thrift.MetricsThriftServerSourceFactoryImpl$FactoryStorage.<init>(MetricsThriftServerSourceFactoryImpl.java:35)
at org.apache.hadoop.hbase.thrift.MetricsThriftServerSourceFactoryImpl$FactoryStorage.<clinit>(MetricsThriftServerSourceFactoryImpl.java:34)
at org.apache.hadoop.hbase.thrift.MetricsThriftServerSourceFactoryImpl.createThriftTwoSource(MetricsThriftServerSourceFactoryImpl.java:52)
at org.apache.hadoop.hbase.thrift.ThriftMetrics.<init>(ThriftMetrics.java:72)
at org.apache.hadoop.hbase.thrift2.ThriftServer.run(ThriftServer.java:473)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
at org.apache.hadoop.hbase.thrift2.ThriftServer.main(ThriftServer.java:374)
3、问题分析&排查
这个报错基本可以认定是jar包冲突导致的,不过问题的难点在于如何定位到有问题的jar
之前遇到过hive由于jar冲突导致的启动失败问题,记录在:一个Hive curator-client.jar包冲突问题排查解决_org.apache.curator.shaded_Java小田的博客-CSDN博客
排查问题的思路可以借鉴,不过hbase比hive的情况更复杂一点
通过日志和查看代码,找到一个关键的配置文件:/usr/hdp/3.0.1.0-187/hbase/conf/hadoop-metrics2-hbase.properties
其中比较关键的配置如下:
*.timeline.plugin.urls=file:///usr/lib/ambari-metrics-hadoop-sink/ambari-metrics-hadoop-sink.jar
hbase.sink.timeline.class=org.apache.hadoop.metrics2.sink.timeline.HadoopTimelineMetricsSink
大致逻辑是,通过一个自定义类加载器,加载外部jar:/usr/lib/ambari-metrics-hadoop-sink/ambari-metrics-hadoop-sink.jar中的org.apache.hadoop.metrics2.sink.timeline.HadoopTimelineMetricsSink类,并调用init方法
把/usr/lib/ambari-metrics-hadoop-sink/ambari-metrics-hadoop-sink.jar下载到本地反编译
然后找到org.apache.hadoop.metrics2.sink.timeline.HadoopTimelineMetricsSink这个类,找到init(SubsetConfiguration conf)方法
仔细看可以发现这里的SubsetConfiguration的包名是org.apache.commons.configuration2.SubsetConfiguration:
而根据上面的异常日志:Exception in thread "main" java.lang.AbstractMethodError: org.apache.hadoop.metrics2.sink.timeline.HadoopTimelineMetricsSink.init(Lorg/apache/commons/configuration/SubsetConfiguration;)V
可以发现两边SubsetConfiguration的包名是不同的,调用的方法和实际加载的类方法,参数不一致,导致了AbstractMethodError
而HadoopTimelineMetricsSink类的加载和init()的方法调用是在org.apache.hadoop.metrics2.impl.MetricsConfig.getPlugin()中进行的,大概率可以推断是MetricsConfig类所在的jar包存在版本冲突
还是通过自己写一个程序来查找这个jar,参考一个Hive curator-client.jar包冲突问题排查解决_org.apache.curator.shaded_Java小田的博客-CSDN博客
中的maven工程
Test.java代码改为:
package com.tianzy.test;
public class Test {
public static void main(String[] args) {
try {
String filePath = Class.forName("org.apache.hadoop.metrics2.impl.MetricsConfig").getProtectionDomain().getCodeSource().getLocation().getFile();
System.out.println(filePath);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
执行mvn package命令打包成hive_test-1.0-SNAPSHOT.jar,上传到服务器上,放到/tmp/test/目录下
接下来比较难办的是要找到hbase thrift2程序的classpath,由于启动脚本比较复杂,想准确找到classpath比较麻烦。
这里采用了偷懒的办法,直接拷贝hbase regionserver进程的classpath:先找到regionserver的pid,然后从/proc/${pid}/environ文件中找到CLASSPATH,拷贝到/tmp/test/habase-classpath.txt文件
再执行命令:
cd /tmp/test
export CLASSPATH=`cat /tmp/test/habase-classpath.txt`:/tmp/test/hive_hook_test-1.0-SNAPSHOT.jar
java com.tianzy.test.TestHbase
输出结果:/data/hdp/3.0.1.0-187/hbase/lib/flink-realtime-data-hbase-1.0-SNAPSHOT.jar
这个一看明显就是自己打的jar包上传的,是谁上传的已经不可考,直接删掉后再尝试启动hbase thrift2,启动成功