[英]hbase InternalScanner and filter in coprocessor
所有:
最近,我用Hbase(0.94.17)編寫了一個協處理器,一個Class擴展了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實用程序代碼:
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;
}
好的,那是我的錯誤。 使用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次后,它會打印另一個異常,這毫無意義。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.