Вопрос или проблема
Я совсем новичок в HBase и Java. Мне удалось запустить образ HBase в Docker, я могу взаимодействовать с ним, используя оболочку hbase, без каких-либо проблем. У меня также есть доступ к интерфейсу для мониторинга HBase. Однако, когда я попытался написать код на Java для взаимодействия с этой HBase, работающей в Docker, я столкнулся с некоторой проблемой.
Мой код на 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 config = HBaseConfiguration.create();
config.set("hbase.zookeeper.quorum", "localhost");
config.set("hbase.zookeeper.property.clientPort", "2181");
// Установить соединение
Connection connection = ConnectionFactory.createConnection(config);
// Доступ к таблице HBase
Table table = connection.getTable(TableName.valueOf("my_table"));
// Извлечение данных для конкретной строки
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("Значение: " + Bytes.toString(value));
// Закрыть ресурсы
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: не удается разрешить c47da4f0ee21,16020,1730323430132 строку 'my_table,row1,99999999999999' в таблице 'hbase:meta' на регионе=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: не удается разрешить 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, версия=2.1.3, sasl=false, ugi=root (auth:SIMPLE), service=AdminService
Я проверил, что сеть контейнера находится в режиме “bridge”, и я успешно использую telnet для подключения к “localhost 2181”
Ответ или решение
Взаимодействие с HBase, работающим в Docker, через Java код
Введение
HBase — это распределенная, колонно-ориентированная база данных, которая предоставляет возможность масштабируемого хранения и обработки больших объемов данных. Поскольку вы уже успешно развернули HBase в Docker и взаимодействуете с ней через shell, следующим шагом является использование Java для работы с HBase API. В данной статье подробно рассмотрим, как правильно настроить соединение с HBase и устранять возникшие ошибки.
Проблема
Ваш текущий код на Java выглядит корректно на первый взгляд, но вызывает ошибки при выполнении. Ошибка java.net.SocketTimeoutException
указывает на то, что ваш код не может разрешить имя хоста для обращения к региону HBase. Это происходит потому, что HBase, работающий в Docker, не всегда доступен стандартными методами с хоста вашей машины.
Анализ кода
Ваш код настроен для использования ZooKeeper, находящегося на локальном компьютере (localhost
), и порта 2181. Однако, когда HBase работает в Docker, важно учитывать следующие моменты:
-
Настройка сети Docker: По умолчанию, если контейнеры Docker работают в режиме "bridge", они могут не быть доступны через
localhost
. Вам нужно использовать IP-адрес контейнера или имя хоста. -
Проблемы с разрешением имени: Ошибка
UnknownHostException
указывает на то, что HBase не может разрешить IP-адрес указанного хоста.
Решение
Вот шаги, которые вы можете предпринять для решения данной проблемы:
-
Узнайте IP-адрес контейнера HBase:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' <container_name>
-
Обновите конфигурацию HBase в Java: Замените
localhost
на IP-адрес контейнера HBase. Код станет следующим:config.set("hbase.zookeeper.quorum", "172.18.0.2"); // Используйте полученный IP-адрес
-
Проверьте сетевые настройки: Если вы по-прежнему столкнетесь с проблемами, попробуйте переключить режим сети Docker на "host", чтобы сделать HBase доступным по локальному хосту:
docker run --network host <hbase_image>
-
Убедитесь в правильной версии библиотек: Убедитесь, что версии используемых библиотек HBase и Hadoop совместимы друг с другом.
-
Настройка логирования: Вы можете устранить предупреждения
log4j
для улучшения контроля ошибок путем добавления базовой конфигурацииlog4j.properties
в ресурсах вашего проекта. Например:log4j.rootLogger=INFO, console log4j.appender.console=org.apache.log4j.ConsoleAppender log4j.appender.console.layout=org.apache.log4j.PatternLayout log4j.appender.console.layout.ConversionPattern=%d{ISO8601} %p [%t] %m%n
Заключение
Проблема с взаимодействием Java и HBase, работающего в Docker, может быть связана с неправильной конфигурацией сетевых параметров. Убедитесь, что ваше приложение на Java может достучаться до HBase через правильные IP-адреса. Следуя описанным выше шагам, вы сможете исправить вашу конфигурацию и успешно получать данные из HBase.
Если у вас все еще возникают вопросы или проблемы, не стесняйтесь обращаться за помощью на специализированные форумы или в сообщества разработчиков.