You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Docker中HBase无法通过Java代码连接的问题求助

问题描述

我是HBase和Java新手,已经在Docker中成功运行HBase镜像,能通过hbase shell正常交互,也能访问HBase监控UI,但编写Java代码连接Docker中的HBase时遇到问题。

我的Java代码

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.TableName;
import org.apache.hadoop.hbase.client.Connection;
import org.apache.hadoop.hbase.client.ConnectionFactory;
import org.apache.hadoop.hbase.client.Table;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.util.Bytes;

public class HBaseExample {
    public static void main(String[] args) {
        try {
            // HBase Configuration
            Configuration config = HBaseConfiguration.create();
            config.set("hbase.zookeeper.quorum", "localhost");
            config.set("hbase.zookeeper.property.clientPort", "2181");

            // Establish connection
            Connection connection = ConnectionFactory.createConnection(config);

            // Access HBase table
            Table table = connection.getTable(TableName.valueOf("my_table"));

            // Retrieve data for a specific row
            Get get = new Get(Bytes.toBytes("row1"));
            Result result = table.get(get);
            byte[] value = result.getValue(Bytes.toBytes("my_cf1"), Bytes.toBytes("col1"));

            System.out.println("Value: " + Bytes.toString(value));

            // Close resources
            table.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

程序运行错误输出

log4j:WARN No appenders could be found for logger (org.apache.hadoop.util.Shell).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
java.net.SocketTimeoutException: callTimeout=60000, callDuration=68630: can not resolve c47da4f0ee21,16020,1730323430132 row 'my_table,row1,99999999999999' on table 'hbase:meta' at region=hbase:meta,,1.1588230740, hostname=c47da4f0ee21,16020,1730323430132, seqNum=-1
        at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:159)
        at org.apache.hadoop.hbase.client.ResultBoundedCompletionService$QueueingFuture.run(ResultBoundedCompletionService.java:80)
        at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136)
        at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
        at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.net.UnknownHostException: can not resolve c47da4f0ee21,16020,1730323430132
        at org.apache.hadoop.hbase.ipc.AbstractRpcClient.createAddr(AbstractRpcClient.java:430)
        at org.apache.hadoop.hbase.ipc.AbstractRpcClient.createBlockingRpcChannel(AbstractRpcClient.java:507)
        at org.apache.hadoop.hbase.client.ConnectionImplementation.lambda$getClient$2(ConnectionImplementation.java:1214)
        at org.apache.hadoop.hbase.util.CollectionUtils.computeIfAbsentEx(CollectionUtils.java:61)
        at org.apache.hadoop.hbase.client.ConnectionImplementation.getClient(ConnectionImplementation.java:1212)
        at org.apache.hadoop.hbase.client.ReversedScannerCallable.prepare(ReversedScannerCallable.java:111)
        at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas$RetryingRPC.prepare(ScannerCallableWithReplicas.java:399)
        at org.apache.hadoop.hbase.client.RpcRetryingCallerImpl.callWithRetries(RpcRetryingCallerImpl.java:105)
        ... 4 more

Docker容器日志

hbase-1  | ==> /hbase/logs/zookeeper.log <==
hbase-1  | 2024-10-30 21:00:20,378 INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181] server.NIOServerCnxnFactory: Accepted socket connection from /192.168.65.1:52662
hbase-1  | 2024-10-30 21:00:20,383 INFO  [NIOServerCxn.Factory:0.0.0.0/0.0.0.0:2181] server.ZooKeeperServer: Client attempting to establish new session at /192.168.65.1:52662
hbase-1  | 2024-10-30 21:00:20,392 INFO  [SyncThread:0] server.ZooKeeperServer: Established session 0x192df1587a8000a with negotiated timeout 90000 for client /192.168.65.1:52662
hbase-1  | 
hbase-1  | ==> /hbase/logs/SecurityAuth.audit <==
hbase-1  | 2024-10-30 21:01:04,285 INFO SecurityLogger.org.apache.hadoop.hbase.Server: Connection from 172.18.0.2:54178, version=2.1.3, sasl=false, ugi=root (auth:SIMPLE), service=AdminService

已确认容器网络为bridge模式,能成功telnet到localhost 2181。


解决方案

问题核心是:Docker容器内的HBase注册到ZooKeeper的是容器内部的hostname(c47da4f0ee21),外部Java客户端无法解析这个hostname,导致连接超时。

方法一:修改HBase容器配置,指定对外暴露地址

  1. 启动容器时添加环境变量,指定HBase对外访问地址为宿主机IP或localhost:

    docker run -d \
      -p 2181:2181 \
      -p 16000:16000 \
      -p 16010:16010 \
      -p 16020:16020 \
      -p 16030:16030 \
      -e HBASE_MANAGES_ZK=true \
      -e HBASE_REGIONSERVER_HOSTNAME=宿主机IP或localhost \
      -e HBASE_MASTER_HOSTNAME=宿主机IP或localhost \
      --name hbase \
      harisekhon/hbase:latest
    

    注:不同HBase镜像的环境变量名称可能有差异,需根据实际镜像调整。

  2. 或进入容器修改hbase-site.xml:

    • 进入容器:docker exec -it hbase bash
    • 编辑/hbase/conf/hbase-site.xml,添加/修改以下配置:
      <property>
        <name>hbase.master.address</name>
        <value>宿主机IP:16000</value>
      </property>
      <property>
        <name>hbase.regionserver.address</name>
        <value>宿主机IP:16020</value>
      </property>
      <property>
        <name>hbase.regionserver.hostname</name>
        <value>宿主机IP</value>
      </property>
      <property>
        <name>hbase.master.hostname</name>
        <value>宿主机IP</value>
      </property>
      
    • 重启容器:docker restart hbase

方法二:宿主机hosts文件添加映射

  1. 获取容器内部IP:docker inspect hbase | grep "IPAddress",得到类似172.18.0.2的地址
  2. 在宿主机/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows)中添加一行:
    172.18.0.2 c47da4f0ee21
    
  3. 重新运行Java程序即可。

方法三:调整Java客户端配置

在代码中添加配置,强制客户端使用指定地址访问regionserver:

Configuration config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "localhost");
config.set("hbase.zookeeper.property.clientPort", "2181");
// 添加以下配置
config.set("hbase.regionserver.address", "localhost:16020");
config.set("hbase.master.address", "localhost:16000");

内容的提问来源于stack exchange,提问作者Romee Zhou

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 19:04:53