hbase快速计算行数

pxq42qpu  于 2021-06-26  发布在  Java
关注(0)|答案(12)|浏览(604)

现在我实现了行计数 ResultScanner 这样地

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

如果达到百万次计算的数据是大的,我想实时计算,我不想使用mapreduce
如何快速计算行数。

23c0lvtd

23c0lvtd1#

在hbase中使用rowcounter 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>...]
    ]
pbgvytdp

pbgvytdp2#

有两种方法可以快速地从hbase表中获取行数
情景1
如果hbase表大小很小,则使用有效用户登录hbase shell并执行

>count '<tablename>'

例子

>count 'employee'

6 row(s) in 0.1110 seconds

情景2
如果hbase表的大小很大,则执行内置的rowcounter map reduce job:login to hadoop machine with valid user and execute:

/$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
rlcwz9us

rlcwz9us3#

您可以使用hbase中的count方法来计算行数。但是,对一个大表的行进行计数可能会很慢。count'tablename'[间隔]
返回值是行数。
此操作可能需要很长时间(运行“$hadoop\u home/bin/hadoop jar hbase.jar rowcount”以运行计数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
rseugnpd

rseugnpd4#

你可以在这里找到示例:

/**
     * 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;
    }
uqzxnwby

uqzxnwby5#

如果您使用的是扫描仪,请在扫描仪中尝试让它返回尽可能少的限定符。实际上,返回的限定符应该是可用的最小限定符(字节大小)。这将大大加快你的扫描速度。
不幸的是,这只会扩大到目前为止(数百万亿?)。更进一步说,您可以实时执行此操作,但首先需要运行mapreduce作业来计算所有行。
将mapreduce输出存储在hbase的单元格中。每次添加一行时,将计数器递增1。每次删除一行时,减小计数器。
当需要实时访问行数时,可以在hbase中读取该字段。
没有快速的方法来计算行数,否则会按比例缩放。你只能数得这么快。

4zcjmb1e

4zcjmb1e6#

使用hbase附带的hbase rowcount map/reduce作业

j2cgzkjk

j2cgzkjk7#

简单、有效、高效地计算hbase中的行数:
每当您插入一行时,就会触发此api,该api将递增该特定单元格。

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

检查该表中的行数。只需对特定的行“count”使用“get”或“scan”api。
通过使用此方法,可以在不到一毫秒的时间内获得行计数。

zlhcx6iw

zlhcx6iw8#

您可以使用自hbase 0.92以来可用的协处理器。请参阅协处理器和聚合协议及示例

bweufnob

bweufnob9#

转到hbase主目录并运行此命令,
./bin/hbase org.apache.hadoop.hbase.mapreduce.rowcounter'namespace:tablename'
这将启动mapreduce作业,输出将显示hbase表中存在的记录数。

wfauudbj

wfauudbj10#

你可以试试hbase api方法!
org.apache.hadoop.hbase.client.co处理器.aggregationclient

i7uaboj4

i7uaboj411#

要在适当的群集上计算hbase表记录计数,还必须设置map reduce作业队列名称:

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

lvmkulzt12#

如果你不能使用 RowCounter 不管出于什么原因,这两个过滤器的组合应该是获得计数的最佳方式:

FirstKeyOnlyFilter() AND KeyOnlyFilter()

这个 FirstKeyOnlyFilter 将导致扫描程序只返回找到的第一个列限定符,而不是扫描程序返回表中的所有列限定符,这将最小化网络带宽。简单地选择一个列限定符返回怎么样?如果您可以保证每一行都有列限定符,那么这将是可行的,但是如果不是这样,那么您将得到一个不准确的计数。
这个 KeyOnlyFilter 将导致扫描仪只返回列族,而不会返回列限定符的任何值。这进一步减少了网络带宽,在一般情况下,这不会导致太多的减少,但是在边缘情况下,前一个过滤器拾取的第一列恰好是一个非常大的值。
我试着和他玩 scan.setCaching 但结果到处都是。也许这会有帮助。
我在开始和停止之间有1600万行,我做了以下伪经验测试:

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

感谢@tucker和@kennycason的提示。

相关问题