HBase BufferedMutator против производительности PutList

Недавно я наткнулся на класс HBase BufferedMutator, который можно использовать для пакетной вставки и удаления. Ранее я использовал список, чтобы поместить данные как hTable.put(putList) сделать то же самое. Сравнительный анализ моего кода, похоже, тоже не показал большой разницы, где я вместо этого делал mutator.mutate(putList);, Есть ли значительное улучшение производительности использования BufferedMutator по сравнению с PutList?

1 ответ

Решение

Короткий ответ

BufferedMutator как правило, обеспечивает лучшую пропускную способность, чем просто использование Table#put(List<Put>) но нуждается в правильной настройке hbase.client.write.buffer, hbase.client.max.total.tasks, hbase.client.max.perserver.tasks а также hbase.client.max.perregion.tasks за хорошую производительность.

объяснение

Когда вы передаете список пут на клиент HBase, он группирует путы по регионам назначения и группирует эти группы по серверу регионов назначения. Один запрос RPC отправляется для каждой партии. Это сокращает накладные расходы rpc, особенно в тех случаях, когда значения Puts очень малы, что делает значительными накладные расходы rpc на запрос.

Table Клиент немедленно отправляет все Puts на серверы региона и ждет ответа. Это означает, что любой пакет, который может произойти, ограничен числом Puts в одном вызове API, и вызовы API являются синхронными с точки зрения вызывающего. Тем не менее BufferedMutator продолжает буферизовать Puts в буфере и решает сбросить буферизованные PUT на основе текущего размера буфера в фоновых потоках, обернутых классом с именем AsyncProcess, С точки зрения вызывающего абонента, каждый вызов API все еще является синхронным, но вся стратегия буферизации дает намного лучшую пакетную обработку. Модель фоновой очистки также обеспечивает непрерывный поток запросов, что в сочетании с улучшенной пакетной обработкой означает возможность поддержки большего количества клиентских потоков. Однако из-за этой стратегии буферизации, чем больше буфер, тем меньше задержка на операцию, которую видит вызывающая сторона, но можно поддерживать более высокую пропускную способность, имея гораздо большее количество клиентских потоков.

Вот некоторые из конфигураций, которые контролируют пропускную способность BufferedMutator:

hbase.client.write.buffer: Размер (в байтах) буфера (чем выше, тем выше пиковая пропускная способность, но больше памяти)

hbase.client.max.total.tasks: Число ожидающих запросов в кластере до того, как AsyncProcess начнет блокировать запросы (чем выше, тем лучше, но может истощить процессор на клиенте или вызвать перегрузку на серверах)

hbase.client.max.perserver.tasks: Число ожидающих запросов для одного сервера региона до того, как AsyncProcess начнет блокировать запросы.

hbase.client.max.perregion.tasksКоличество ожидающих запросов на регион.

Кроме того, ради полноты, само собой разумеется, что если узкое место находится на стороне сервера, а не на стороне клиента, вы не увидите значительного прироста производительности при использовании BufferedMutator над Table на клиенте.

Другие вопросы по тегам