我对 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”
无法解析的主机名
c47da4f0ee21
似乎是Docker生成的默认网络名称。我怀疑 ZooKeeper 返回 c47da4f0ee21
作为区域服务器地址,并且您的 Java 客户端无法解析此主机名,因为它不是 Docker 桥接网络的一部分。所以解决这个问题的一种方法是:
hbasenet
hbasenet
。hbasenet
.为了进一步分析问题,我建议查看 HBase 读取流程。简而言之,它涉及以下步骤:
客户端初始化:
定位数据:
请求处理:
数据检索: