协处理器中的hbase内部扫描与过滤

xiozqbni  于 2021-06-09  发布在  Hbase
关注(0)|答案(1)|浏览(499)

全部:
最近,我在hbase(0.94.17)中编写了一个协处理器,这个类扩展了baseendpointcoprocessor,一个rowcount方法来计算一个表的行数。
我有个问题。
如果我没有在scan中设置一个过滤器,我的代码可以很好地用于两个表。一个表有1000000行,另一个表有160000000行。数那张大table花了大约2分钟。
但是,如果我在scan中设置了一个过滤器,它只能在小表上工作。它将在更大的表上抛出一个例外。org.apache.hadoop.hbase.ipc。execrpcinvoker$1@2c88652b,java.io.ioexception:java.io.ioexception:java.lang.indexoutofboundsexception:索引:0,大小:0
相信我,我反复检查我的代码。
所以,要用filter计算我的表,我必须编写以下愚蠢的代码,首先,我没有在scan中设置filter,然后,在我得到一行记录之后,我编写了一个方法来过滤它。
两张table都能用。
但我不知道为什么。
我试图阅读hregion.java中的scanner源代码,但是我没有得到它。
所以,如果你知道答案,请帮帮我。谢谢您。

  1. @Override
  2. public long rowCount(Configuration conf) throws IOException {
  3. // TODO Auto-generated method stub
  4. Scan scan = new Scan();
  5. parseConfiguration(conf);
  6. Filter filter = null;
  7. if (this.mFilterString != null && !mFilterString.equals("")) {
  8. ParseFilter parse = new ParseFilter();
  9. filter = parse.parseFilterString(mFilterString);
  10. // scan.setFilter(filter);
  11. }
  12. scan.setCaching(this.mScanCaching);
  13. InternalScanner scanner = ((RegionCoprocessorEnvironment) getEnvironment()).getRegion().getScanner(scan);
  14. long sum = 0;
  15. try {
  16. List<KeyValue> curVals = new ArrayList<KeyValue>();
  17. boolean hasMore = false;
  18. do {
  19. curVals.clear();
  20. hasMore = scanner.next(curVals);
  21. if (filter != null) {
  22. filter.reset();
  23. if (HbaseUtil.filterOneResult(curVals, filter)) {
  24. continue;
  25. }
  26. }
  27. sum++;
  28. } while (hasMore);
  29. } finally {
  30. scanner.close();
  31. }
  32. return sum;
  33. }

以下是我的hbase util代码:

  1. public static boolean filterOneResult(List<KeyValue> kvList, Filter filter) {
  2. if (kvList.size() == 0)
  3. return true;
  4. KeyValue kv = kvList.get(0);
  5. if (filter.filterRowKey(kv.getBuffer(), kv.getRowOffset(), kv.getRowLength())) {
  6. return true;
  7. }
  8. for (KeyValue kv2 : kvList) {
  9. if (filter.filterKeyValue(kv2) == Filter.ReturnCode.NEXT_ROW) {
  10. return true;
  11. }
  12. }
  13. filter.filterRow(kvList);
  14. if (filter.filterRow())
  15. return true;
  16. else
  17. return false;
  18. }
dffbzjpn

dffbzjpn1#

好吧,那是我的错。在我使用jdb调试代码之后,我得到了以下异常,

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

很明显,我的成绩表是空的。

  1. hasMore = scanner.next(curVals);

这意味着,如果我在扫描中使用过滤器,这个曲线列表可能是空的,但是hasmore是真的。
但是我想,如果一个记录被过滤了,它应该跳转到下一行,并且这个列表永远不应该是空的。我错了。
我的客户端没有在我的控制台上打印任何远程错误消息,它只是捕获这个远程异常,然后重试。在重试10次之后,它会打印另一个异常,这是没有意义的。

相关问题