Hbase客户端无法连接到远程Hbase服务器。

14
我已经为远程服务器编写了以下HBase客户端类:
System.out.println("Hbase Demo Application ");

            // CONFIGURATION

                // ENSURE RUNNING
            try {
                HBaseConfiguration config = new HBaseConfiguration();
                config.clear();
                config.set("hbase.zookeeper.quorum", "192.168.15.20");
                config.set("hbase.zookeeper.property.clientPort","2181");
                config.set("hbase.master", "192.168.15.20:60000");
                //HBaseConfiguration config = HBaseConfiguration.create();
    //config.set("hbase.zookeeper.quorum", "localhost");  // Here we are running zookeeper locally
                HBaseAdmin.checkHBaseAvailable(config);


                System.out.println("HBase is running!");
            //  createTable(config);    
                //creating a new table
                HTable table = new HTable(config, "mytable");
                System.out.println("Table mytable obtained ");  
                addData(table);
            } catch (MasterNotRunningException e) {
                System.out.println("HBase is not running!");
                System.exit(1);
            }catch (Exception ce){ ce.printStackTrace();

它正在抛出一些异常:

Oct 17, 2011 1:43:54 PM org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation getMaster
INFO: getMaster attempt 0 of 1 failed; no more retrying.
java.net.ConnectException: Connection refused
    at sun.nio.ch.SocketChannelImpl.checkConnect(Native Method)
    at sun.nio.ch.SocketChannelImpl.finishConnect(SocketChannelImpl.java:567)
    at org.apache.hadoop.net.SocketIOWithTimeout.connect(SocketIOWithTimeout.java:206)
    at org.apache.hadoop.net.NetUtils.connect(NetUtils.java:404)
    at org.apache.hadoop.hbase.ipc.HBaseClient$Connection.setupIOstreams(HBaseClient.java:328)
    at org.apache.hadoop.hbase.ipc.HBaseClient.getConnection(HBaseClient.java:883)
    at org.apache.hadoop.hbase.ipc.HBaseClient.call(HBaseClient.java:750)
    at org.apache.hadoop.hbase.ipc.HBaseRPC$Invoker.invoke(HBaseRPC.java:257)
    at $Proxy4.getProtocolVersion(Unknown Source)
    at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:419)
    at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:393)
    at org.apache.hadoop.hbase.ipc.HBaseRPC.getProxy(HBaseRPC.java:444)
    at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.getMaster(HConnectionManager.java:359)
    at org.apache.hadoop.hbase.client.HBaseAdmin.<init>(HBaseAdmin.java:89)
    at org.apache.hadoop.hbase.client.HBaseAdmin.checkHBaseAvailable(HBaseAdmin.java:1215)
    at com.ifkaar.hbase.HBaseDemo.main(HBaseDemo.java:31)
HBase is not running!

你能告诉我为什么会抛出异常,代码有什么问题以及如何解决吗。


2
在提出新问题之前,请接受您旧问题的答案。如果您不给予任何反馈,那么没有人会愿意回答您的问题。 - frail
好的。从现在开始,我会这样做。我是这个网站的新用户。通常我会为帮助我的答案投票。谢谢。 - Ali Raza
config.set("hbase.master", "192.168.15.20:60000");你能把这行注释掉然后再试一下吗? - frail
我已经再次尝试了,但结果仍然相同。 - Ali Raza
1
你能否telnet 192.168.15.20:2181(是否存在连接问题?) - frail
显示剩余2条评论
5个回答

22

这个问题是由于您的HBase服务器的hosts文件引起的。
您只需要编辑HBase服务器的/etc/hosts文件。
从该文件中删除localhost条目,并将localhost条目放在HBase服务器IP前面。

例如,您的HBase服务器的/etc/hosts文件应该像这样:

127.0.0.1 localhost
192.166.66.66 xyz.hbase.com hbase

您需要这样更改,即删除localhost:

# 127.0.0.1 localhost # line commented out
192.166.66.66 xyz.hbase.com hbase localhost # note: localhost added here
这是因为当远程机器询问hbase服务器机器HMaster的运行位置时,它告诉它正在本地主机上运行。
所以,如果条目是127.0.0.1,那么HBase服务器将返回此地址,并且远程机器将开始在自己的机器上(本地)查找HMaster。
当我们将其更改为HBase服务器IP时,一切正常工作:)

2
更改后必须重新启动Hbase。'netstat -a | grep 6000'命令在此处非常有用,因为它显示主节点绑定到本地接口。 - Wacław Borowiec
2
有没有更优雅的方式来做这件事呢?我们能否在某个配置文件中指定 xyz.hbase.com 而不是修改 hosts 文件?谢谢。这种解决方案对我实际上是可行的,但并不够优雅。 - DB Tsai
1
谁能理解他想说什么。请编辑此帖以使其可读。 - seb
1
@seb说:“删除127.0.0.1行,将localhost添加到真实IP地址行中。” - Eric Hartford
但是,在删除127.0.0.1并将localhost添加到IP地址后,SSH无法建立连接(“ssh username@ip-addr”和“ssh username@localhost”都会显示“远程主机关闭连接”),以重新启动HBase实例。有人知道可能出现什么问题吗? - vivek_nk
这不是将“localhost”本质上重命名为“192.166.66.66”吗?现在,尝试从该计算机使用“localhost”的任何其他应用程序都将最终通过网络进出。 - c z

2

我同意.. HBase对于/etc/hosts配置非常敏感.. 为了让上述Java代码正常工作,我必须正确设置hbase-site.xml中的zeekeeper绑定属性..例如:我必须将其设置如下:

{property}
  {name}hbase.zookeeper.quorum{/name}
  {value}www.remoterg12.net{/value}      {!-- this is the externally accessible domain --}
{/property}
{property}
  {name}hbase.zookeeper.property.clientPort{/name}
  {value}2181{/value}              {!-- everything needs to be externally accessible --}
{/property}
{property}
  {name}hbase.master.info.port{/name}    {!--   http://www.remoterg12.net:60010/ --}
  {value}60010{/value}
{/property}
{property}
  {name}hbase.master.info.bindAddress{/name}
  {value}www.remoterg12.net{/value}      {!-- Use this to access the GUI console, --}
{/property}

远程GUI可以清晰地展示绑定域的情况。例如,在“GUI Web控制台”中,“[HBase Master]”属性应该像这样:www.remoterg12.net:60010(不应该是localhost:60010)......是的,我确实需要正确地调整/etc/hosts,因为我不想搞乱现有的Apache配置 :-)

0

我也遇到了与HBase 1.1.3相同的问题。 两台虚拟机(Ubuntu)在同一网络上。日志显示客户端可以访问Zookeeper,但无法访问HBase服务器。

简而言之,在服务器(server_hostame)的/etc/hosts文件中删除以下行:

127.0.1.1 server_hostname server_hostname

并将此IP地址127.x.y.z添加到您的服务器上(本地)网络中:

192.x.y.z server_hostname

我在客户端和服务器端尝试了很多组合。在独立模式下,我认为没有更好的方法。

对此并不感到自豪。必须搞乱网络配置,却无法提供一个能够远程连接到服务器的 HBase shell 客户端(欢迎来到 Java 世界的幻觉...)

在服务器端,将文件 conf/hbase-site.xml 留空即可。你不需要在这里放置 Zookeeper 配置,默认即可。

etc/regionservers 同理。将其保留默认条目(localhost),因为我认为在独立模式下它并不真正关心(我尝试将 server_hostname 放入其中,但当然这行不通)。

在客户端上,如果要解析服务器,则必须通过主机名知道服务器,因此请在客户端的 /etc/hosts 文件中添加一个条目以指定服务器。

作为奖励,我会给出我的 sbt 配置以及一些完整的客户端工作代码,因为 HBase 团队似乎在过去的四年里已经在拉斯维加斯花光了文档预算(再次欢迎来到 Java/Scala 的“商业就绪”世界)。

build.sbt:

libraryDependencies ++= Seq(
  ...
  "org.apache.hadoop" % "hadoop-core" % "1.2.1",
  "org.apache.hbase" % "hbase" % "1.1.2",
  "org.apache.hbase" % "hbase-client" % "1.1.2",
)

some_client_code.scala:

import org.apache.hadoop.hbase.HBaseConfiguration
import org.apache.hadoop.hbase.client.{HTable, Put, HBaseAdmin}
import org.apache.hadoop.hbase.util.Bytes

val hbaseConf = HBaseConfiguration.create()
hbaseConf.set("hbase.zookeeper.quorum", "server_hostname")
HBaseAdmin.checkHBaseAvailable(hbaseConf)

val table = new HTable(hbaseConf, "my_hbase_table")
val put = new Put(Bytes.toBytes("row_key"))
put.add(Bytes.toBytes("cf"), Bytes.toBytes("colId1"), Bytes.toBytes("foo"))

0
同样的问题可以通过编辑Hbase目录中的conf/regionservers文件,在其中添加Hbase服务器(远程)来解决。然后就不需要更改etc/hosts文件了。
编辑conf/regionservers后将如下所示:
localhost  
ip address of the remote hbase server

例如

localhost              
10.132.258.366

请您能否详细解释一下这种方法?我不太明白您的意思。 - seb
这似乎不起作用,仅编辑/etc/host文件只能使HBase远程客户端工作。 - prassee

0

我知道回答这个问题已经太晚了,但我想分享一下我解决类似问题的方法。

我遇到了同样的问题,尝试从Java程序和CLI设置zookeeper quorum,但都没有成功。

我正在使用CDH 5.7.7和HBase版本1.1.0。最终,我不得不将几个配置导出到Hadoop类路径中以解决此问题。以下是我导出的配置。

export HADOOP_CLASSPATH=/etc/hadoop/conf:/usr/share/cmf/lib/cdh5/hbase-protocol-0.98.1-cdh5.5.0.jar:/etc/hbase/conf:/driven/conf

希望这能有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接