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容器配置,指定对外暴露地址
启动容器时添加环境变量,指定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镜像的环境变量名称可能有差异,需根据实际镜像调整。
或进入容器修改
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文件添加映射
- 获取容器内部IP:
docker inspect hbase | grep "IPAddress",得到类似172.18.0.2的地址 - 在宿主机
/etc/hosts(Linux/macOS)或C:\Windows\System32\drivers\etc\hosts(Windows)中添加一行:172.18.0.2 c47da4f0ee21 - 重新运行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
相关产品推荐
相关产品推荐

