hbase InternalScanner и фильтр в сопроцессоре

Все:

Недавно я написал сопроцессор в Hbase(0.94.17), класс расширяет 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: индекс: 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;
    }

1 ответ

Хорошо, это была моя ошибка. После того, как я использую 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 повторных попыток выдается еще одно исключение, которое не имеет смысла.

Другие вопросы по тегам