hbase协处理器是否提供跨表的原子性?

6yoyoihd  于 2021-06-09  发布在  Hbase
关注(0)|答案(2)|浏览(333)

我正在尝试使用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);                                                                                                                                          
        }
    }                                                        
}

我想知道:
是吗 PuttableB 如果后续的 PuttableA 失败?
相反,如果我把上面的钩子改成 postPut() 然后这个钩子的结果失败了,原来的结果呢 Put 触发了 postPut() 还成功吗?

a5g8bdjr

a5g8bdjr1#

索引put是用不同的行键插入的,因此这两个突变不能是原子的。最明显的情况是,索引put被写入一个完全不同的区域服务器。

disho6za

disho6za2#

如果后续的表A放入失败,上面的表B放入是否会持久化?
合同 prePut 它在 Put 区域服务器上发生变异操作。因此,如果 prePut 抛出异常,调用路径被中断,请求将永远不会到达regionserver mutate操作。
相反,如果我将上面的钩子改为postput(),然后这个钩子的结果失败,那么触发postput()的原始put是否仍然成功?
是的,反过来说 postPut 它包含在regionserver注册变异后应用的操作。如果从这个实现中抛出一个异常,它将呈现给调用方,但是 Put 将在hbase中注册。

相关问题