Вопрос по hbase, bigdata, hadoop – Hbase быстро посчитать количество строк

45

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

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

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

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

Ваш Ответ

12   ответов
-1

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

Не могли бы вы предоставить немного больше контекста для вашего ответа, а также несколько ссылок на соответствующую документацию?
28

ок. Но да, подсчет строк в большой таблице может быть медленным. Count & apos; tablename & apos; [Интервал]

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

Эта операция может занять продолжительное время (Выполнить & # x2018; $ HADOOP_HOME / bin / hadoop jar hbase.jar rowcount & # x2019; запустить работу подсчета mapreduce). Текущий счетчик показан каждые 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
@articuno точно
Этот счетчик работает очень медленно и доступен только из оболочки hbase. Для больших таблиц его не рекомендуется использовать.
5

Whenever you insert a row trigger this API which will increment that particular cell.

Htable.incrementColumnValue(Bytes.toBytes("count"), Bytes.toBytes("details"), Bytes.toBytes("count"), 1);

To check number of rows present in that table. Just use "Get" or "scan" API for that particular Row 'count'.

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

А что если загрузка данных происходит не через hbase API, например, оптом
Нет. Я хочу сказать, что "time hbase use инкремент больше времени". Я хочу бежать быстрее cldo
что если строка уже существует и ее обновили? это может считать дополнительные строки, верно?
Это хороший способ. Но время, в которое инкремент использования hbase, больше времени, которое hbase помещает в данные. cldo
1

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

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

6

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's 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 для чаевых.

3

который доступен с HBase 0.92. Увидетьсопроцессор а такжеAggregateProtocol а такжепример

Это сработало для меня, просто простая команда "count" a myTable ", спасибо :)
0

Two ways Worked for me to get count of rows from hbase table with Speed

Scenario #1

Если размер таблицы hbase небольшой, войдите в оболочку hbase с действительным пользователем и выполните

>count '<tablename>'

пример

>count 'employee'

6 row(s) in 0.1110 seconds

Scenario #2

Если размер таблицы hbase большой, то выполнить встроенную карту RowCounter, чтобы уменьшить объем работ: Войдите в систему пользователя hadoop с действительным пользователем и выполните:

/$HBASE_HOME/bin/hbase org.apache.hadoop.hbase.mapreduce.RowCounter '<tablename>'

Пример:

 /$HBASE_HOME/bin/hbase org.apache.hadoop.hbase.mapreduce.RowCounter 'employee'

     ....
     ....
     ....
     Virtual memory (bytes) snapshot=22594633728
                Total committed heap usage (bytes)=5093457920
        org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper$Counters
                ROWS=6
        File Input Format Counters
                Bytes Read=0
        File Output Format Counters
                Bytes Written=0
3

кластере YARN, необходимо также настроить карту для уменьшения имени очереди заданий:

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

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

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

Usage: RowCounter [options] 
    <tablename> [          
        --starttime=[start] 
        --endtime=[end] 
        [--range=[startKey],[endKey]] 
        [<column1> <column2>...]
    ]
@cldo, ты должен принять этот ответ
K, запустил это, где он печатает ответ?org.apache.hadoop.hbase.mapreduce.RowCounter$RowCounterMapper$Counters ROWS=55438 & lt; - что это?
1

/**
     * 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;
    }
Есть ли способ доказать этоconfiguration.setLong("hbase.client.scanner.caching", 1000); работает? Например, если я его установлю, а потом позвонюscanner.getCaching(), он вернется-1.
7

HBase mapcount map / сокращение рабочих мест которые включены в HBase

Я использовал исходный код для примера rowcount, и чтобы сохранить результат в переменной, я получил счетчик, используя:job.getCounters().findCounter(RowCounter.RowCounterMapper.Counters.ROWS).getValue();
1

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

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

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

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

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

@KennyCason Хорошо, я нашел это: ИспользуйтеFirstKeyOnlyFilter() AND KeyOnlyFilter(),KeyOnlyFilter предотвратит передачу значения столбца по сети.
@KennyCason Ладно, после тестирования он, кажется, выберет первую ячейку и вернет только эту. Почему вы предлагаете это вместо предложения @ Tucker вернуть наименьший квалификатор? Например, если первое значение ключа выбраноFirstKeyOnlyFilter имеет действительно большое значение, то это замедлит сканирование. С другой стороны, если вы выберете квалификатор, который имеет наименьшее значение, но этот классификатор не появляется во всех строках, которые вы хотите сосчитать, то вы получите неточный счет.
@KennyCason Что именно делаетFirstKeyOnlyFilter делать? Из [thrift docs] (я не мог понять это объяснение:[FirstKeyOnlyFilter] returns only the first key-value from each row - Значит ли это, что он просто выбирает первую ячейку и возвращает ту?
На самом деле вместо «возврата наименьшего количества квалификаторов, насколько это возможно» ты пользуешьсяFirstKeyOnlyFilter, в качестве фильтра сканирования

Похожие вопросы