我正在尝试使用hbase协处理器来创建辅助索引。它似乎起作用了。我想知道这种方法是否提供了某种程度的原子性。
下面是一些示例代码。它观察到 Put
s开启 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()
还成功吗?
2条答案
按热度按时间a5g8bdjr1#
索引put是用不同的行键插入的,因此这两个突变不能是原子的。最明显的情况是,索引put被写入一个完全不同的区域服务器。
disho6za2#
如果后续的表A放入失败,上面的表B放入是否会持久化?
合同
prePut
它在Put
区域服务器上发生变异操作。因此,如果prePut
抛出异常,调用路径被中断,请求将永远不会到达regionserver mutate操作。相反,如果我将上面的钩子改为postput(),然后这个钩子的结果失败,那么触发postput()的原始put是否仍然成功?
是的,反过来说
postPut
它包含在regionserver注册变异后应用的操作。如果从这个实现中抛出一个异常,它将呈现给调用方,但是Put
将在hbase中注册。