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 に put を実行すると実行されます。コードにコメントがあります (検索してください): "The following call is setting up a strange".
prePut メソッドが SOURCE_TABLE でのみ実行され、INDEX_TABLE では実行されないことを確認するデバッグ プリントをログに設定しました。しかし、コプロセッサーで INDEX_TABLE に 1 つの put しか実行していないにもかかわらず、なぜこの奇妙な再帰が起こっているのか理解できません。
また、ソース テーブルへの put アクションが 1 つだけであることも確認しました。