我正在尝试使用HBase协处理器来创建二级索引。它似乎工作。我想知道这种方法是否提供任何程度的原子性。
以下是一些示例代码。它会在Put
上观察tableA
并在tableB
中创建倒排索引:
public class MyObserver extends BaseRegionObserver {
public static final TableName TABLE_A = TableName.valueOf("tableA");
public static final TableName TABLE_B = TableName.valueOf("tableB");
public static final byte[] family = Bytes.toBytes("f");
public static final byte[] qualA = Bytes.toBytes("qualA");
public static final byte[] qualB = Bytes.toBytes("qualB");
private Connection connection;
@Override
public void start(CoprocessorEnvironment env) throws IOException {
Configuration config = env.getConfiguration();
connection = ConnectionFactory.createConnection(config);
}
@Override
public void stop(CoprocessorEnvironment env) throws IOException {
connection.close();
}
@Override
public void prePut(ObserverContext<RegionCoprocessorEnvironment> env, Put put, WALEdit edit, Durability durability) throws IOException {
TableName tableName = env.getEnvironment().getRegionInfo().getTable();
if (!tableName.equals(TABLE_A)) {
return;
}
byte[] key = put.getRow();
byte[] value = CellUtil.cloneValue(put.get(family, qualA).get(0));
Put putB = new Put(value);
putB.addColumn(family, qualB, key);
try (Table tableB = connection.getTable(TABLE_B)) {
tableB.put(putB);
}
catch (IOException e) {
logger.info("Error: {}", e);
}
}
}
我想知道:
Put
到tableB
失败,上面的Put
到tableA
是否会被保留?postPut()
然后此挂钩的结果失败,那么触发Put
的原始postPut()
是否仍然成功?答案 0 :(得分:1)
使用不同的行键插入索引Put,因此这两个突变不能是原子的。显而易见的情况是将index put写入完全不同的区域服务器。
答案 1 :(得分:1)
如果后续的Put to tableA失败,那么上面的putB是否会被持久化?
prePut
的合同是它在区域服务器上发生Put
变异操作之前应用其操作。因此,如果prePut
抛出异常,则调用路径被中断,请求将永远不会到达regionserver mutate操作。
相反,如果我将上面的钩子更改为postPut()然后这个钩子的结果失败,那么触发postPut()的原始Put是否仍然成功?
是的,相反,postPut
的合同是它包含在突变向regionserver注册后应用的操作。如果从此实现中抛出异常,它将显示给调用者,但Put
将在此时向HBase注册。