簡體   English   中英

hbase InternalScanner和協處理器中的過濾器

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM