首页 > 解决方案 > 如何将 HBase 行转换为对象数组

问题描述

我有一个休息 API,它使用 java 客户端从 HBase 检索很多行。

我已经实现了以下代码来将 hbase 行转换为数组数组。

List<List<String>> finalList = new ArrayList<List<String>>();
        ResultScanner scanner = table.getScanner(scan);
        List<String> rowSection = new ArrayList<String>();
        try {
            for (Result result = scanner.next(); (result != null); result = scanner.next()) {
                rowSection.clear();
                for (Cell cell : result.listCells()) {
                    String value = Bytes.toString(CellUtil.cloneValue(cell));
                    rowSection.add(value);
                }
                finalList.add(rowSection);
            }
            System.out.println("ARRAY SIZE: " + finalList.size());
        } finally {
            if (scanner != null) {
                scanner.close();
            }
        }

我可以轻松地将其转换为对象数组,但我不确定这是否是转换 hbase 结果的正确方法。

有没有更高效的方法来做到这一点,还是有一些自动的功能?

标签: javaarraysobjecthbasecloudera

解决方案


我怀疑您代码中的关键性能瓶颈是您正在执行scanner.next() 而不指定要返回多少行。这样,您将对每一行的集群进行往返。最好指示一次要返回多少行,以便将它们全部打包到一个 RPC 调用中。此处的正确参数取决于您的行实际有多大(即列内容)以及您在服务器上的内存。使用此设置,但我通常使用数千或数万用于小行。通过这种方式,您应该会看到显着的加速。

为了清楚起见,用一个例子编辑:

这将在一个 RPC 中向服务器返回 1 行,其中包含该行的所有列:

Result result = scanner.next()

这将返回 20 行,其中每一行的所有相关列,都在单个 RPC 中到服务器:

Result result = scanner.next(20)

如果实际存在的满足您的扫描的行少于 20 行,则扫描将返回任何可用的行。

所以尝试做一个两级循环:外部级别检查结果是否为空或小于您要求的结果(即没有更多可用结果),而内部循环实际上循环每个 RPC 返回的所有行。我没有测试过这个,但是像这样:

   int HOW_MANY_ROWS = 20
    Result result[];
    do
                {
                    result = m_scanner.next(HOW_MANY_ROWS);
                    for(Result row : result)
                    {
                        byte rowKey[] = row.getRow());
                        // rest of your code for this row goes here
                    }   
                    if(scanRes.result < HOW_MANY_ROWS)
                    break;
                }

像这样的东西应该比你现在拥有的要快得多,特别是如果你的扫描必须返回数千行。


推荐阅读