HBase笔记之踩坑记录:Java远程连接到HBase
HBase服务器在一台腾讯云上,本地Windows系统连不上,代码如下:
package cc11001100.hbase.baseOperation; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.HBaseConfiguration; import org.apache.hadoop.hbase.TableName; import org.apache.hadoop.hbase.client.Admin; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; import java.io.IOException; /** * @author CC11001100 */ public class JavaConnectToHbaseTest { public static void main(String[] args) throws IOException { Configuration conf = HBaseConfiguration.create(); conf.set("hbase.zookeeper.quorum", "xx.xx.xx.xx"); conf.set("hbase.zookeeper.property.clientPort", "2181"); Connection conn = ConnectionFactory.createConnection(conf); System.out.println(conn); Admin admin = conn.getAdmin(); System.out.println(admin.tableExists(TableName.valueOf("test:user"))); } }
输出如下:
hconnection-0x674658f7 Exception in thread "main" org.apache.hadoop.hbase.client.RetriesExhaustedException: Failed after attempts=16, exceptions: Sun Dec 09 23:41:54 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:41:54 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: Call to localhost/127.0.0.1:16000 failed on local exception: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list: localhost/127.0.0.1:16000 Sun Dec 09 23:41:54 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: Call to localhost/127.0.0.1:16000 failed on local exception: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list: localhost/127.0.0.1:16000 Sun Dec 09 23:41:54 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: Call to localhost/127.0.0.1:16000 failed on local exception: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list: localhost/127.0.0.1:16000 Sun Dec 09 23:41:55 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: Call to localhost/127.0.0.1:16000 failed on local exception: org.apache.hadoop.hbase.ipc.FailedServerException: This server is in the failed servers list: localhost/127.0.0.1:16000 Sun Dec 09 23:41:57 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:00 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:06 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:17 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:28 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:39 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:42:50 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.net.ConnectException: Call to localhost/127.0.0.1:16000 failed on connection exception: org.apache.hbase.thirdparty.io.netty.channel.AbstractChannel$AnnotatedConnectException: Connection refused: no further information: localhost/127.0.0.1:16000 Sun Dec 09 23:43:10 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master Sun Dec 09 23:43:31 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master Sun Dec 09 23:43:51 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master Sun Dec 09 23:44:11 CST 2018, RpcRetryingCaller{globalStartTime=1544370111222, pause=100, maxAttempts=16}, org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:144) at org.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:3084) at org.apache.hadoop.hbase.client.HBaseAdmin.executeCallable(HBaseAdmin.java:3076) at org.apache.hadoop.hbase.client.HBaseAdmin.listTableDescriptors(HBaseAdmin.java:323) at org.apache.hadoop.hbase.client.HBaseAdmin.listTableDescriptors(HBaseAdmin.java:312) at cc11001100.hbase.tableOperation.TableOperationUsageDemo.main(TableOperationUsageDemo.java:43) Caused by: org.apache.hadoop.hbase.MasterNotRunningException: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master at org.apache.hadoop.hbase.client.ConnectionImplementation$MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1157) at org.apache.hadoop.hbase.client.ConnectionImplementation.getKeepAliveMasterService(ConnectionImplementation.java:1216) at org.apache.hadoop.hbase.client.ConnectionImplementation.getMaster(ConnectionImplementation.java:1205) at org.apache.hadoop.hbase.client.MasterCallable.prepare(MasterCallable.java:57) at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:105) ... 5 more Caused by: java.io.IOException: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master at org.apache.hadoop.hbase.client.ConnectionImplementation.get(ConnectionImplementation.java:1994) at org.apache.hadoop.hbase.client.ConnectionImplementation.access$500(ConnectionImplementation.java:138) at org.apache.hadoop.hbase.client.ConnectionImplementation$MasterServiceStubMaker.makeStubNoRetries(ConnectionImplementation.java:1118) at org.apache.hadoop.hbase.client.ConnectionImplementation$MasterServiceStubMaker.makeStub(ConnectionImplementation.java:1151) ... 9 more Caused by: org.apache.zookeeper.KeeperException$NoNodeException: KeeperErrorCode = NoNode for /hbase/master at org.apache.zookeeper.KeeperException.create(KeeperException.java:111) at org.apache.zookeeper.KeeperException.create(KeeperException.java:51) at org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient$ZKTask$1.exec(ReadOnlyZKClient.java:174) at org.apache.hadoop.hbase.zookeeper.ReadOnlyZKClient.run(ReadOnlyZKClient.java:329) at java.lang.Thread.run(Thread.java:748)
可以看到第一行打印出了conn,说明成功连接到了zookeeper服务器,否则这一步就会报错了,所以是在从zookeeper取得master信息尝试去连接master的时候出错的。
然后看了下报错信息中的地址我就很奇怪,为什么是连接的localhost:16000呢,这个信息存放到zookeeper上,登录到zookeeper看下当前的master绑定到哪里了:
悲剧了,为什么是localhost呢难道只监听了回环地址吗,然后在master机器上看16000端口的监听情况:
我本来以为在hbase-site.xml中会有一个选项用来设置master监听的网卡地址,毕竟这是业内约定俗成的做法了,鬼知道hbase这么奇葩,折腾半天也没找到相关的设置,倒是找到了另一种方法解决这个问题。
hbase会绑定到当前的hostname所解析到的地址,所以手动改下hostname,然后在/etc/hosts中将hostname解析到要绑定的网卡上,启动时就会去解析hostname,然后监听到解析到的ip上。
修改hostname可以修改/etc/hostname,这个永久有效但是需要重启生效,或者使用hostname临时修改hostname:
[root@foobar ~]# hostname master
然后在/etc/hosts中加入一条,将主机名解析到要绑定的ip上:
10.xx.xx.xx master
启动hbase,查看端口监听情况:
然后再去zookeeper看下master绑定情况:
当客户端来zookeeper寻找master的时候会根据得到的master的域名解析到的ip去寻找,所以还需要在客户端加一条master到服务器公网ip的映射,我这里是Windows系统,在C:\Windows\System32\drivers\etc\hosts中加一个映射:
140.xx.xx.xx master
Java代码无需修改,再运行一次:
hconnection-0x5a56cdac true
OK,成功连接。
总结:
我想了一下这样设计的原因应该就是master的地址是存在zookeeper上的,其它客户端去zookeeper取这个地址然后连接,这是一个常量,如果放ip的话,会涉及到网卡的内网ip和外网ip的处理,因为hbase要监听在网卡的内网地址上,如果可以配置的话在配置文件中的必须是一个内网ip,如果将这个内网ip给zookeeper,内网的其它机器能够连接上,但外网连接就悲剧了,所以比较灵活的方式还是放域名(这里是hostname),这样客户端根据自己的位置将hostname解析为不同的地址,内网的话解析为内网地址,外网的话解析为公网地址,整体上没啥毛病,只是不太好的部分是监听的时候从hostname到网卡ip的这一段的处理有点不太好,个人感觉不如提供多提供两个选项,一个用来配置监听网卡ip,默认是0.0.0.0,另一个是配置一个域名作为放到zookeeper上的master的地址,默认取当前的hostname。
.