FineBI中连接Phoenix失败的问题的排查过程
标题里说是finebi中连接phoenix, 实际上应该是java中使用phoenix, 实际上这个过程还是有点曲折, 而且与我手写的Java程序连接phoenix有些许不同, 不知道的话就是个坑, 这里记录一下.
这里还需要注意的一个是JDBC URL的写法:
本例子:
jdbc:phoenix:hdpzk01.bigdata.host:2181:/hbase-unsecure
前面部分jdbc:phoenix:
是固定的, 后面hdpzk01.bigdata.host
是hbase所注册的zookeeper的地址, 如果有多个, 可以用逗号隔开, 如: hdpzk01,hdpzk02:/hbase-unsecure
, 最后一个冒号后面的/hbase-unsecure
是hbase在zk中的znode.
背景交代一下
公司的phoenix中jar包版本为4.14(phoenix-4.14.0-HBase-1.1-client.jar
). finebi官方文档推荐使用的是4.12版本, 但是4.12版本连接phoenix的时候报下面的错误.
16:54:28 Druid-ConnectionPool-Create-443705156jdbc:phoenix:hdpzk01.bigdata.host:2181:/hbase-unsecure ERROR [com.fr.third.alibaba.druid.pool.DruidDataSource] create connection error, url: jdbc:phoenix:hdpzk01.bigdata.host:2181:/hbase-unsecure, errorCode 103, state 08004
java.sql.SQLException: ERROR 103 (08004): Unable to establish connection.
at org.apache.phoenix.exception.SQLExceptionCode$Factory$1.newException(SQLExceptionCode.java:489)
at org.apache.phoenix.exception.SQLExceptionInfo.buildException(SQLExceptionInfo.java:150)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.openConnection(ConnectionQueryServicesImpl.java:418)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.access$500(ConnectionQueryServicesImpl.java:257)
at org.apache.phoenix.query.ConnectionQueryServicesImpl$12.call(ConnectionQueryServicesImpl.java:2384)
at org.apache.phoenix.query.ConnectionQueryServicesImpl$12.call(ConnectionQueryServicesImpl.java:2360)
at org.apache.phoenix.util.PhoenixContextExecutor.call(PhoenixContextExecutor.java:76)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.init(ConnectionQueryServicesImpl.java:2360)
at org.apache.phoenix.jdbc.PhoenixDriver.getConnectionQueryServices(PhoenixDriver.java:255)
at org.apache.phoenix.jdbc.PhoenixEmbeddedDriver.createConnection(PhoenixEmbeddedDriver.java:150)
at org.apache.phoenix.jdbc.PhoenixDriver.connect(PhoenixDriver.java:221)
at com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1461)
at com.fr.third.alibaba.druid.pool.DruidAbstractDataSource.createPhysicalConnection(DruidAbstractDataSource.java:1525)
at com.fr.third.alibaba.druid.pool.DruidDataSource$CreateConnectionThread.run(DruidDataSource.java:2153)
Caused by: java.io.IOException: java.lang.reflect.InvocationTargetException
at org.apache.hadoop.hbase.client.ConnectionFactory.createConnection(ConnectionFactory.java:240)
at org.apache.hadoop.hbase.client.ConnectionManager.createConnection(ConnectionManager.java:431)
at org.apache.hadoop.hbase.client.ConnectionManager.createConnectionInternal(ConnectionManager.java:340)
at org.apache.hadoop.hbase.client.HConnectionManager.createConnection(HConnectionManager.java:144)
at org.apache.phoenix.query.HConnectionFactory$HConnectionFactoryImpl.createConnection(HConnectionFactory.java:47)
at org.apache.phoenix.query.ConnectionQueryServicesImpl.openConnection(ConnectionQueryServicesImpl.java:409)
... 11 more
Caused by: java.lang.reflect.InvocationTargetException
at sun.reflect.GeneratedConstructorAccessor331.newInstance(Unknown Source)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
at org.apache.hadoop.hbase.client.ConnectionFactory.createConnection(ConnectionFactory.java:238)
... 16 more
Caused by: java.lang.NoClassDefFoundError: Could not initialize class org.apache.hadoop.hbase.protobuf.ProtobufUtil
at org.apache.hadoop.hbase.ClusterId.parseFrom(ClusterId.java:64)
at org.apache.hadoop.hbase.zookeeper.ZKClusterId.readClusterIdZNode(ZKClusterId.java:75)
at org.apache.hadoop.hbase.client.ZooKeeperRegistry.getClusterId(ZooKeeperRegistry.java:105)
at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.retrieveClusterId(ConnectionManager.java:905)
at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.<init>(ConnectionManager.java:648)
... 20 more
是不是缺少依赖HBase和HDFS的配置文件
在自己写的Java代码中连接phoenix, 需要提供HBase和HDFS的配置文件, 这个可以直接从Ambari UI或者服务器配置目录里下载到. 具体的就是下面三个文件.
- core-site.xml
- hdfs-site.xml
- hbase-site.xml
把这三个文件与jar包放到同一个目录里(lib目录), 但是问题并没有得到解决.
更换jar包版本到4.14
因为finebi官方推荐使用是4.12的, 这个落后于我们正在使用的phoenix两个小版本, 为了排除这个问题的干扰, 从phoenix的库中拷贝4.14jar包到finebi的lib目录中. 但是这个时候再启动finebi的时候发现已经起不来了.
再咨询finebi售后技术
售后技术: 如果是驱动的问题的话,可以将4.14版本驱动,用winrar打开,将里面的javax文件夹删掉,再放到BI里面启动
简言之就是将jar包中的javax文件夹删除. 重新将jar包拷贝到lib目录里的后, FineBI可以正常启动了. 但是在测试连接时, 报下面的错误, 看情况是没有读到上面所述的三个配置文件.
ERROR 726 (43M10): Inconsistent namespace mapping properties. Cannot initiate connection as SYSTEM:CATALOG is found but client does not have phoenix.schema.isNamespaceMappingEnabled enabled
那么应该怎么操作呢?
需要将三个配置文件也添加到4.14的驱动jar包中..
技术售后给的图片
总结一下
折腾了好久, 其实操作还是很简单的.
- 找到和phoenix版本相匹配的phoenix-client.jar
- 去掉jar中的javax文件夹
- 将上面所述三个配置文件加入到phoenix-client.jar中.
- 放到finebi的lib目录里.
这里要吐槽一下finebi的文档, 误导性很强
附上我自己手写的Java连接phoenix的代码, 很简单, 方便测试
源代码
import java.sql.*;
import java.util.Properties;
public class Main {
public static void main(String[] args) {
Connection conn = null;
Statement stat = null;
ResultSet rst = null;
Properties prop = new Properties();
try {
Class.forName("org.apache.phoenix.jdbc.PhoenixDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try {
conn = DriverManager.getConnection("jdbc:phoenix:hdpzk01.bigdata.host:2181:/hbase-unsecure");
stat = conn.createStatement();
rst = stat.executeQuery("select 1");
while (rst.next()) {
System.out.println("result: "rst.getString(1));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {conn.close();System.out.println("conn.close"); } catch (SQLException e) { e.printStackTrace(); }
try {stat.close();System.out.println("stat.close"); } catch (SQLException e) { e.printStackTrace(); }
try {rst.close();System.out.println("rst.close"); } catch (SQLException e) { e.printStackTrace(); }
}
}
}