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。
.