0

全部:

最近,我在Hbase(0.94.17)中写了一个协处理器,A类扩展了BaseEndpointCoprocessor,一个行计数方法来计算一个表的行数。

我遇到了一个问题。

如果我没有在扫描中设置过滤器,我的代码适用于两个表。一个表有 1,000,000 行,另一个有 160,000,000 行。计算更大的桌子大约需要 2 分钟。

但是,如果我在扫描中设置过滤器,它只适用于小表。它会在更大的桌子上抛出异常。org.apache.hadoop.hbase.ipc.ExecRPCInvoker$1@2c88652b,java.io.IOException:java.io.IOException:java.lang.IndexOutOfBoundsException:索引:0,大小:0

相信我,我一遍又一遍地检查我的代码。

所以,要用过滤器计算我的表,我必须编写以下愚蠢的代码,首先,我没有在扫描中设置过滤器,然后,在我得到一条记录后,我编写了一个过滤它的方法。

它适用于两张桌子。

但我不知道为什么。

我尝试阅读 HRegion.java 中的扫描仪源代码,但是我没有得到它。

所以,如果你知道答案,请帮助我。谢谢你。

@Override
    public long rowCount(Configuration conf) throws IOException {
        // TODO Auto-generated method stub
        Scan scan = new Scan();
        parseConfiguration(conf);
        Filter filter = null;
        if (this.mFilterString != null && !mFilterString.equals("")) {
            ParseFilter parse = new ParseFilter();
            filter = parse.parseFilterString(mFilterString);
            // scan.setFilter(filter);
        }

        scan.setCaching(this.mScanCaching);
        InternalScanner scanner = ((RegionCoprocessorEnvironment) getEnvironment()).getRegion().getScanner(scan);
        long sum = 0;

        try {
            List<KeyValue> curVals = new ArrayList<KeyValue>();
            boolean hasMore = false;
            do {
                curVals.clear();
                hasMore = scanner.next(curVals);
                if (filter != null) {
                    filter.reset();
                    if (HbaseUtil.filterOneResult(curVals, filter)) {
                        continue;
                    }
                }
                sum++;
            } while (hasMore);

        } finally {
            scanner.close();
        }
        return sum;
    }

以下是我的 hbase util 代码:

public static boolean filterOneResult(List<KeyValue> kvList, Filter filter) {
        if (kvList.size() == 0)
            return true;
        KeyValue kv = kvList.get(0);
        if (filter.filterRowKey(kv.getBuffer(), kv.getRowOffset(), kv.getRowLength())) {
            return true;
        }

        for (KeyValue kv2 : kvList) {
            if (filter.filterKeyValue(kv2) == Filter.ReturnCode.NEXT_ROW) {
                return true;
            }
        }
        filter.filterRow(kvList);
        if (filter.filterRow())
            return true;
        else
            return false;
    }
4

1 回答 1

0

好吧,这是我的错。使用 jdb 调试代码后,出现以下异常,

 "org.apache.hadoop.ipc.RemoteException: java.io.IOException: java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
    at java.util.ArrayList.rangeCheck(ArrayList.java:635)
    at java.util.ArrayList.get(ArrayList.java:411)

很明显,我的结果列表是空的。

hasMore = scanner.next(curVals);

这意味着,如果我在扫描中使用过滤器,则此 curVals 列表可能为空,但 hasMore 为真。

但我想,如果一条记录被过滤,它应该跳到下一行,这个列表永远不应该是空的。我错了。

而且我的客户端没有在我的控制台上打印任何远程错误消息,它只是捕获了这个远程异常,然后重试。重试10次后,又打印一个异常,没有意义。

于 2014-09-22T03:55:37.920 回答