在HBase数据库中,我想通过使用附加的“链接”表来创建二级索引。我已按照此答案中给出的示例:Create secondary index using coprocesor 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操作只有一个。
答案 0 :(得分:0)
我解决了我的问题。结果是我多次添加同一个观察者错误地认为它在Hbase重启后会丢失。
同样,对INDEX_TABLE的.put调用无效的原因是因为我没有为它设置值,而只是一个rowkey,错误地认为这是可能的。然而,HBase并没有抛出任何例外,只是没有执行PUT,没有给出任何信息,这可能会让新手对这项技术感到困惑。