Вторичный индекс HBase с сопроцессором-наблюдателем, .put в таблице индексов приводит к рекурсии

В базе данных HBase я хочу создать вторичный индекс, используя дополнительную «связывающую» таблицу. Я следовал примеру, приведенному в этом ответе: Создать вторичный индекс с помощью сопроцессора HBase

Я не очень хорошо знаком со всей концепцией HBase, и я читал несколько примеров по вопросу создания вторичных индексов. Я подключаю сопроцессор только к одной таблице, например:

disable 'Entry2'
alter 'Entry2', METHOD => 'table_att', 'COPROCESSOR' => '/home/user/hbase/rootdir/hcoprocessors.jar|com.acme.hobservers.EntryParentIndex||'
enable 'Entry2'

Исходный код его выглядит следующим образом:

public class EntryParentIndex extends BaseRegionObserver{

private static final Log LOG = LogFactory.getLog(CoprocessorHost.class);

private HTablePool pool = null;

private final static String  INDEX_TABLE                       = "EntryParentIndex";
private final static String  SOURCE_TABLE                      = "Entry2";

@Override
  public void start(CoprocessorEnvironment env) throws IOException {
    pool = new HTablePool(env.getConfiguration(), 10);
 }

@Override
  public void prePut(
      final ObserverContext<RegionCoprocessorEnvironment> observerContext,
      final Put put,
      final WALEdit edit,
      final boolean writeToWAL)
    throws IOException {

    try {

         final List<KeyValue> filteredList = put.get(Bytes.toBytes ("data"),Bytes.toBytes("parentId"));
         byte [] id = put.getRow(); //Get the Entry ID

         KeyValue kv=filteredList.get( 0 ); //get Entry PARENT_ID
         byte[] parentId=kv.getValue();


        HTableInterface htbl = pool.getTable(Bytes.toBytes(INDEX_TABLE));

        //create row key for the index table
        byte[] p1=concatTwoByteArrays(parentId, ":".getBytes()); //Insert a semicolon between two UUIDs
        byte[] rowkey=concatTwoByteArrays(p1, id);

        Put indexput  = new Put(rowkey);

        //The following call is setting up a strange? recursion, resulting
        //...in thesame prePut method invoken again and again. Interestingly
        //...the recursion limits itself up to 6 times. The actual row does not
        //...get inserted into the INDEX_TABLE
        htbl.put(indexput);


        htbl.close();

    }
    catch ( IllegalArgumentException ex) {  }

  }


  @Override
  public void stop(CoprocessorEnvironment env) throws IOException {
    pool.close();
  }

  public static final byte[] concatTwoByteArrays(byte[] first, byte[] second) {
        byte[] result = Arrays.copyOf(first, first.length + second.length);
        System.arraycopy(second, 0, result, first.length, second.length);
        return result;
    }

}

Это выполняется, когда я выполняю команду SOURCE_TABLE. В коде есть комментарий (поищите): "Следующий вызов вызывает странную настройку".

Я установил отладочную печать в журнале, подтверждающую, что метод prePut выполняется только для SOURCE_TABLE и никогда для INDEX_TABLE. Тем не менее, я не понимаю, почему происходит эта странная рекурсия, несмотря на то, что в сопроцессоре я выполняю только одну операцию, помещенную в INDEX_TABLE.

Я также подтвердил, что действие put в исходной таблице снова только одно.


person PatlaDJ    schedule 29.04.2013    source источник


Ответы (1)


Я исправил свою проблему. Оказалось, что я несколько раз добавлял один и тот же наблюдатель, ошибочно думая, что он теряется после перезапуска Hbase.

Также причина, по которой вызов .put для INDEX_TABLE не работал, заключается в том, что я не установил для него значение, а только строку, ошибочно думая, что это возможно. Тем не менее, HBase не выдавал никаких исключений, просто не выполнял PUT, не предоставляя никакой информации, что может сбить с толку новичков в этой технологии.

person PatlaDJ    schedule 29.04.2013