所有
最近,我在Hbase(0.94.17)中编写了一个协处理器,A类扩展了BaseEndpointCoprocessor,这是一种计数一个表行的rowcount方法。
我遇到了问题。
如果我没有在扫描中设置过滤器,我的代码适用于两个表。一个表有1,000,000行,另一个表有160,000,000行。计算更大的桌子需要大约2分钟。
但是,如果我在扫描中设置过滤器,它只适用于小型表。它会在更大的桌子上抛出异常。 org.apache.hadoop.hbase.ipc.ExecRPCInvoker$1@2c88652b,java.io.IOException:java.io.IOException:java.lang.IndexOutOfBoundsException:Index:0,Size: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;
}
答案 0 :(得分: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为true。
但是我想,如果过滤了一条记录,它应该跳到下一行,这个列表永远不应该是空的。我错了。
我的客户端没有在我的控制台上打印任何远程错误消息,它只是捕获这个远程异常,然后重试。 在重试10次之后,它会打印另一个例外,这是没有意义的。