Подтвердить что ты не робот

Hbase быстро подсчитывает количество строк

Прямо сейчас я реализую подсчет строк над ResultScanner следующим образом

for (Result rs = scanner.next(); rs != null; rs = scanner.next()) {
    number++;
}

Если данные, достигающие миллионов вычислений времени, являются большими. Я хочу вычислить в реальном времени, что я не хочу использовать Mapreduce

Как быстро подсчитать количество строк.

4b9b3361

Ответ 1

Использовать RowCounter в HBase RowCounter - это задание mapreduce для подсчета всех строк таблицы. Это хорошая утилита для использования в качестве проверки работоспособности, чтобы гарантировать, что HBase может читать все блоки таблицы, если есть какие-либо проблемы несоответствия метаданных. Он будет выполнять mapreduce все в одном процессе, но он будет работать быстрее, если у вас есть кластер MapReduce для его использования.

$ hbase org.apache.hadoop.hbase.mapreduce.RowCounter <tablename>

Usage: RowCounter [options] 
    <tablename> [          
        --starttime=[start] 
        --endtime=[end] 
        [--range=[startKey],[endKey]] 
        [<column1> <column2>...]
    ]

Ответ 2

Вы можете использовать метод count в hbase для подсчета количества строк. Но да, подсчет строк большой таблицы может быть slow.count 'tablename' [interval]

Возвращаемое значение - это количество строк.

Эта операция может занять долгое время (запустить "$ HADOOP_HOME/bin/hadoop jar hbase.jar rowcount, чтобы запустить задание для преобразования counting). Отображается текущий счетчик каждые 1000 строк по умолчанию. Интервал отсчета может быть опционально задан. сканирование Кэширование включено по подсчету по умолчанию. Размер кеша по умолчанию - 10 строк. Если ваши строки невелики по размеру, вы можете увеличить Параметр.

Примеры:

hbase> count 't1'

hbase> count 't1', INTERVAL => 100000

hbase> count 't1', CACHE => 1000

hbase> count 't1', INTERVAL => 10, CACHE => 1000

Те же команды также могут быть запущены в таблице. Предположим, что у вас есть ссылка на таблицу 't1', соответствующие команды:

hbase> t.count

hbase> t.count INTERVAL => 100000

hbase> t.count CACHE => 1000

hbase> t.count INTERVAL => 10, CACHE => 1000

Ответ 4

Если вы не можете использовать RowCounter по какой-либо причине, то комбинация этих двух фильтров должна быть оптимальным способом получения счета:

FirstKeyOnlyFilter() AND KeyOnlyFilter()

FirstKeyOnlyFilter приведет к тому, что сканер только вернет первый классификатор столбцов, который он находит, в отличие от сканера, возвращающего все классификаторы столбцов в таблице, что минимизирует полосу пропускания сети. Как насчет простого выбора одного столбца для возврата? Это будет работать, если вы можете гарантировать, что этот разделитель столбцов существует для каждой строки, но если это неверно, вы получите неточное количество.

KeyOnlyFilter приведет к тому, что сканер вернет только семейство столбцов и не вернет никакого значения для классификатора столбцов. Это еще больше уменьшает пропускную способность сети, которая в общем случае не учитывает значительную часть сокращения, но может быть краевой случай, когда первый столбец, выбранный предыдущим фильтром, просто оказывается чрезвычайно большим значением.

Я пробовал играть с scan.setCaching, но результаты были повсюду. Возможно, это может помочь.

У меня было 16 миллионов строк между началом и остановкой, что я сделал следующее псевдоэмпирическое тестирование:

With FirstKeyOnlyFilter and KeyOnlyFilter activated:

    With caching not set (i.e., the default value), it took 188 seconds.
    With caching set to 1, it took 188 seconds
    With caching set to 10, it took 200 seconds
    With caching set to 100, it took 187 seconds
    With caching set to 1000, it took 183 seconds.
    With caching set to 10000, it took 199 seconds.
    With caching set to 100000, it took 199 seconds.

With FirstKeyOnlyFilter and KeyOnlyFilter disabled:

    With caching not set, (i.e., the default value), it took 309 seconds

Я не потрудился провести надлежащее тестирование на этом, но кажется ясным, что FirstKeyOnlyFilter и KeyOnlyFilter хороши.

Кроме того, ячейки в этой конкретной таблице очень маленькие - поэтому я думаю, что фильтры были бы еще лучше в другой таблице.


Вот пример кода Java:

import java.io.IOException;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

import org.apache.hadoop.hbase.filter.RowFilter;
import org.apache.hadoop.hbase.filter.KeyOnlyFilter; 
import org.apache.hadoop.hbase.filter.FirstKeyOnlyFilter; 
import org.apache.hadoop.hbase.filter.FilterList;

import org.apache.hadoop.hbase.filter.CompareFilter.CompareOp;
import org.apache.hadoop.hbase.filter.RegexStringComparator; 

public class HBaseCount {
    public static void main(String[] args) throws IOException {
        Configuration config = HBaseConfiguration.create();

        HTable table = new HTable(config, "my_table");

        Scan scan = new Scan(
            Bytes.toBytes("foo"), Bytes.toBytes("foo~")
        );

        if (args.length == 1) {
            scan.setCaching(Integer.valueOf(args[0]));
        }
        System.out.println("scan caching is " + scan.getCaching());

        FilterList allFilters = new FilterList();
        allFilters.addFilter(new FirstKeyOnlyFilter());
        allFilters.addFilter(new KeyOnlyFilter());

        scan.setFilter(allFilters);

        ResultScanner scanner = table.getScanner(scan);

        int count = 0;

        long start = System.currentTimeMillis();

        try {
            for (Result rr = scanner.next(); rr != null; rr = scanner.next()) {
                count += 1;
                if (count % 100000 == 0) System.out.println(count);
            }
        } finally {
            scanner.close();
        }

        long end = System.currentTimeMillis();

        long elapsedTime = end - start;

        System.out.println("Elapsed time was " + (elapsedTime/1000F));

    }
}


Вот пример кода pychbase:

    from pychbase import Connection
    c = Connection()
    t = c.table('my_table')
    # Under the hood this applies the FirstKeyOnlyFilter and KeyOnlyFilter
    # similar to the happybase example below
    print t.count(row_prefix="foo")

Вот пример кода Happybase:

    from happybase import Connection
    c = Connection(...)
    t = c.table('my_table')
    count = 0
    for _ in t.scan(filter='FirstKeyOnlyFilter() AND KeyOnlyFilter()'):
        count += 1

    print count

Благодаря @Tuckr и @KennyCason для подсказки.

Ответ 5

Простой, эффективный и эффективный способ подсчета строки в HBASE:

  • Всякий раз, когда вы вставляете строку, запускайте этот API, который будет увеличивать эту конкретную ячейку.

    Htable.incrementColumnValue(Bytes.toBytes("count"), Bytes.toBytes("details"), Bytes.toBytes("count"), 1);
    
  • Проверить количество строк, присутствующих в этой таблице. Просто используйте API-интерфейс "Получить" или "Сканировать" для этого определенного количества строк.

Используя этот метод, вы можете получить количество строк меньше чем за миллисекунду.

Ответ 7

Чтобы подсчитать количество записей таблицы Hbase в соответствующем кластере YARN, вы также должны указать, чтобы карта уменьшала имя очереди заданий:

hbase org.apache.hadoop.hbase.mapreduce.RowCounter -Dmapreduce.job.queuename= < Your Q Name which you have SUBMIT access>
 < TABLE_NAME>

Ответ 8

Если вы используете сканер, попробуйте в своем сканере вернуть наименьшее количество квалификаторов. Фактически, квалификатор (ы), который вы возвращаете, должен быть самым маленьким (в байтах), который у вас есть. Это значительно ускорит сканирование.

К сожалению, пока это будет только масштабным (миллионы-миллиарды?). Чтобы сделать это дальше, вы можете сделать это в режиме реального времени, но сначала вам нужно запустить задание mapreduce для подсчета всех строк.

Сохраните вывод Mapreduce в ячейке в HBase. Каждый раз, когда вы добавляете строку, увеличивайте счетчик на 1. Каждый раз, когда вы удаляете строку, уменьшайте счетчик.

Когда вам нужно получить доступ к количеству строк в реальном времени, вы читаете это поле в HBase.

Нет быстрого способа подсчета строк иначе, чем масштабируется. Вы можете рассчитывать только так быстро.

Ответ 9

U можно найти пример здесь:

/**
     * Used to get the number of rows of the table
     * @param tableName
     * @param familyNames
     * @return the number of rows
     * @throws IOException
     */
    public long countRows(String tableName, String... familyNames) throws IOException {
        long rowCount = 0;
        Configuration configuration = connection.getConfiguration();
        // Increase RPC timeout, in case of a slow computation
        configuration.setLong("hbase.rpc.timeout", 600000);
        // Default is 1, set to a higher value for faster scanner.next(..)
        configuration.setLong("hbase.client.scanner.caching", 1000);

        AggregationClient aggregationClient = new AggregationClient(configuration);
        try {
            Scan scan = new Scan();
            if (familyNames != null && familyNames.length > 0) {
                for (String familyName : familyNames) {
                    scan.addFamily(Bytes.toBytes(familyName));
                }
            }
            rowCount = aggregationClient.rowCount(TableName.valueOf(tableName), new LongColumnInterpreter(), scan);
        } catch (Throwable e) {
            throw new IOException(e);
        }
        return rowCount;
    }

Ответ 10

Перейдите в домашний каталог Hbase и запустите эту команду,

./bin/hbase org.apache.hadoop.hbase.mapreduce.RowCounter 'namespace: tablename'

Это запустит задание mapreduce, и на выходе будет отображаться количество записей, существующих в таблице hbase.

Ответ 11

Вы можете попробовать hbase api методы!

org.apache.hadoop.hbase.client.coprocessor.AggregationClient