在HBase數據庫中,我想通過使用額外的「鏈接」表創建一個二級索引。我已按照這個答案給出的例子:Create secondary index using coprocesor HBase觀察者協處理器的HBase二級索引,索引表上的.put會導致遞歸
我不是非常好熟悉的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上。
我也確認放在源表上的操作又是隻有一個。
您應該將此答案標記爲「已接受」。 – 2013-10-20 17:30:09