2013-04-29 56 views
1

在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上。

我也確認放在源表上的操作又是隻有一個。

回答

0

我解決了我的問題。結果是我多次添加同一個觀察者,錯誤地認爲它在Hbase重新啓動後會丟失。

此外,爲什麼INDEX_TABLE的.put調用不工作的原因是因爲我沒有給它設置一個值,而只是一個rowkey,錯誤地認爲這是可能的。然而,HBase並沒有拋出任何優點,只是沒有執行PUT,沒有給出任何信息,這可能會讓新技術人員對這項技術感到困惑。

+0

您應該將此答案標記爲「已接受」。 – 2013-10-20 17:30:09