Постоянное число запросов HBase занимает почти ровно 5000 мс для успешного завершения, несмотря на меньшее время ожидания. Не знаю почему
Мой клиент использует org.apache.hbase:hbase-client:2.1.0"
и сервер работает 1.2.0-cdh5.11.1
(1.2.0-cdh5.11.0
в альтернативном тестовом кластере).
Мой клиент очень прост, он создает Connection
класс при запуске (этот класс - в соответствии с рекомендациями Apache - совместно используется потоками, поскольку он тяжелый и потокобезопасный). Затем для каждого запроса он создает Table
класс и делает .exists(new Get(rowKey))
операция.
Ну вот так:
Connection conn = ConnectionFactory.createConnection(hbaseConfig);
а также
final Table table = conn.getTable(tableName);
return table.exists(new Get(context.getKey()));
В большинстве случаев задержка запроса к HBase и обратно составляет в худшем случае 40 мс. Обычно это завершается около 10 мс.
Тем не менее, мы замечаем, что случайные запросы занимают около 5000 мс (5 с), но все же успешно завершаются!
И под случайным я имею в виду около 1 запроса в минуту (из 600 в минуту всего, так что маленькая скорость). Но это устойчиво.
Это почти точно около 5 с (+/- 100-200 мс). Это странная часть. Это не шип.
Сначала я подозревал, что это неверная конфигурация клиента, и мне нужно было установить более строгие таймауты, поэтому я установил следующее:
hbaseConfig.set(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
hbaseConfig.set(HConstants.HBASE_CLIENT_PAUSE, "50");
hbaseConfig.set(HConstants.HBASE_CLIENT_OPERATION_TIMEOUT, "2000");
hbaseConfig.set(HConstants.HBASE_RPC_TIMEOUT_KEY, "1500");
hbaseConfig.set(HConstants.HBASE_RPC_SHORTOPERATION_TIMEOUT_KEY, "2000");
hbaseConfig.set(HConstants.HBASE_CLIENT_SCANNER_TIMEOUT_PERIOD, "1500");
hbaseConfig.set(HConstants.ZOOKEEPER_RECOVERABLE_WAITTIME, "2000");
hbaseConfig.set(HConstants.ZK_SESSION_TIMEOUT, "2000");
hbaseConfig.set("zookeeper.recovery.retry", "1");
hbaseConfig.set("zookeeper.recovery.retry.intervalmill","200");
hbaseConfig.set("hbase.ipc.client.socket.timeout.connect", "2000");
hbaseConfig.set("hbase.ipc.client.socket.timeout.read", "2000");
hbaseConfig.set("hbase.ipc.client.socket.timeout.write", "2000");
Другими словами, 5000 мс - это намного больше, чем глобальное время ожидания (как установлено в HConstants.HBASE_CLIENT_OPERATION_TIMEOUT
).
Тем не менее, у меня есть запросы, выполнение которых занимает ~5 с - и делает это успешно.
В дополнение к этим тайм-аутам я изменил использование AsyncConnection
в Connection
(не нужно, чтобы он был асинхронным в любом случае), и я думаю просто сделать GET
звонки вместо exists
,
Но на данный момент я в тупике. Я не вижу никакой собственности, и откуда 5-е место. Это даже не тайм-аут, это действительно успешно!
Кто-нибудь сталкивался с этим раньше? Есть ли способ заставить hbase-клиента генерировать метрики? Метрики на стороне сервера не показывают увеличения задержки (метрики сканирования).
0 ответов
Для нас дампы потоков показали, что время было потрачено на выполнение разрешения DNS с использованием реализации IPv6, а также обнаружили несколько проблем, связанных с задержкой в 5 секунд в собственной библиотеке.
hconnection-0x6fc1d215-shared--pool1-t95"
java.lang.Thread.State: RUNNABLE
at java.net.Inet6AddressImpl.lookupAllHostAddr(Native Method)
at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:929)
at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1324)
at java.net.InetAddress.getAllByName0(InetAddress.java:1277)
at java.net.InetAddress.getAllByName(InetAddress.java:1193)
at java.net.InetAddress.getAllByName(InetAddress.java:1127)
at java.net.InetAddress.getByName(InetAddress.java:1077)
at java.net.InetSocketAddress.<init>(InetSocketAddress.java:220)
at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.getStubKey(ConnectionManager.java:1802)
at org.apache.hadoop.hbase.client.ConnectionManager$HConnectionImplementation.getClient(ConnectionManager.java:1772)
at org.apache.hadoop.hbase.client.ScannerCallable.prepare(ScannerCallable.java:163)
at org.apache.hadoop.hbase.client.ScannerCallableWithReplicas$RetryingRPC.prepare(ScannerCallableWithReplicas.java:409)
at org.apache.hadoop.hbase.client.RpcRetryingCaller.callWithRetries(RpcRetryingCaller.java:134)
at org.apache.hadoop.hbase.client.ResultBoundedCompletionService$QueueingFuture.run(ResultBoundedCompletionService.java:80)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)"Timer-47"
https://github.com/netty/netty/issues/6454
Добавление -Djava.net.preferIPv4Stack=true
принудительное использование стека IPv4, похоже, устранило эту проблему для нас. Мы больше не видим задержки в 5 секунд (скрещены пальцы)