【问题标题】:Do HBase coprocessors provide any atomicity across tables?HBase 协处理器是否提供跨表的原子性?
【发布时间】:2017-09-21 16:57:12
【问题描述】:

我正在尝试使用 HBase 协处理器来创建二级索引。它似乎正在工作。我想知道这种方法是否提供任何程度的原子性。

这里是一些示例代码。它在tableA 上观察Puts 并在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);                                                                                                                                          
        }
    }                                                        
}

我想知道:

  • 如果后续的PuttableA 失败,上面的PuttableB 是否会保持不变?
  • 反之,如果我把上面的钩子改成postPut(),然后这个钩子的结果就失败了,那么原来触发postPut()Put还会成功吗?

【问题讨论】:

  • 您为什么要尝试在 HBase 中构建自己的二级索引?您是否查看过 Phoenix(phoenix.apache.org/secondary_indexing.html) 提供的各种二级索引?这将节省您的时间和精力。
  • @AnilGupta 我有,当然。动机有两个:(i)不想要 Phoenix 的 SQL 层。只想要这一个特定的东西。 (ii) 想探索协处理器 API。我查看了其他索引/交易项目。除了凤凰,你有没有试过?
  • 不,我没试过。但是,你也可以给别人一个旋转(trafodion,拼接机,tephra)。但是,我认为 HBase 之上的大多数库都是 sql 层。似乎用户想要在 nosql 中使用“SQL”。
  • 因为你正在尝试做协处理器并建立你自己的二级索引。您将在 hbase 用户邮件列表中获得有关此主题的更好帮助。所有的提交者都在那里回复。
  • 哦,谢谢,我去看看。很高兴知道这是一个活动列表。

标签: hbase


【解决方案1】:

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

【讨论】:

  • 这就是我的想法。谢谢。
【解决方案2】:

如果后续 Put to tableA 失败,上面的 Put to tableB 是否会被持久化?

prePut 的约定是它在区域服务器上发生Put 突变操作之前应用其操作。因此,如果prePut 抛出异常,调用路径将被中断,请求将永远不会到达 regionserver mutate 操作。

反之,如果我把上面的钩子改成postPut(),然后这个钩子的结果失败了,原来那个触发postPut()的Put还成功吗?

是的,相反,postPut 的合同是它包含在向区域服务器注册突变之后应用的操作。如果此实现引发异常,它将显示给调用者,但此时 Put 将在 HBase 中注册。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-04-05
    • 2014-11-14
    • 1970-01-01
    • 1970-01-01
    • 2018-12-07
    • 1970-01-01
    • 2010-10-15
    • 2019-04-12
    相关资源
    最近更新 更多