通过Java代码与Docker中运行的HBase交互

问题描述 投票:0回答:1

我对 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();
        }
    }
}

当我运行这个程序时,它不会在我的 hbase 表中打印出所需的值,终端输出是:

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”

java docker hadoop hbase
1个回答
0
投票

无法解析的主机名

c47da4f0ee21
似乎是Docker生成的默认网络名称。我怀疑 ZooKeeper 返回
c47da4f0ee21
作为区域服务器地址,并且您的 Java 客户端无法解析此主机名,因为它不是 Docker 桥接网络的一部分。所以解决这个问题的一种方法是:

  1. 使用docker创建网络;称之为
    hbasenet
  2. 启动容器时将 HBase 容器附加到
    hbasenet
  3. 将Java代码打包成镜像。 HBase 健康后,使用 Java 代码启动容器,将其附加到
    hbasenet
    .

为了进一步分析问题,我建议查看 HBase 读取流程。简而言之,它涉及以下步骤:

客户端初始化:

  • 客户端设置配置并与Zookeeper建立连接。

定位数据:

  • 使用ZooKeeper和元表来查找负责目标数据的RegionServer。

请求处理:

  • 客户端向RegionServer发送Get请求。
  • RegionServer 通过检查缓存并可能从 HDFS 读取来处理请求。

数据检索:

  • RegionServer将请求的数据返回给客户端。
© www.soinside.com 2019 - 2024. All rights reserved.