Tephra —— HBase 全局一致性事务支持

  • Tephra 在 Apache HBase 的基础上提供了全局一致性的事务支持。HBase 提供了强一致性的基于行和区域的 ACID 操作支持,但是牺牲了在跨区域操作的支持。这就要求应用开发者花很大力气来确保区域边界上操作的一致性。而 Tephra 提供了全局事务支持,可以夸区域、跨表以及多个 RPC 上简化了应用的开发。

示例代码:

/**
   * A Transactional SecondaryIndexTable.
   */
  public class SecondaryIndexTable {
    private byte[] secondaryIndex;
    private TransactionAwareHTable transactionAwareHTable;
    private TransactionAwareHTable secondaryIndexTable;
    private TransactionContext transactionContext;
    private final TableName secondaryIndexTableName;
    private static final byte[] secondaryIndexFamily =
      Bytes.toBytes("secondaryIndexFamily");
    private static final byte[] secondaryIndexQualifier = Bytes.toBytes('r');
    private static final byte[] DELIMITER  = new byte[] {0};

    public SecondaryIndexTable(TransactionServiceClient transactionServiceClient,
                               HTable hTable, byte[] secondaryIndex) {
      secondaryIndexTableName =
            TableName.valueOf(hTable.getName().getNameAsString() + ".idx");
      HTable secondaryIndexHTable = null;
      HBaseAdmin hBaseAdmin = null;
      try {
        hBaseAdmin = new HBaseAdmin(hTable.getConfiguration());
        if (!hBaseAdmin.tableExists(secondaryIndexTableName)) {
          hBaseAdmin.createTable(new HTableDescriptor(secondaryIndexTableName));
        }
        secondaryIndexHTable = new HTable(hTable.getConfiguration(),
                                          secondaryIndexTableName);
      } catch (Exception e) {
        Throwables.propagate(e);
      } finally {
        try {
          hBaseAdmin.close();
        } catch (Exception e) {
          Throwables.propagate(e);
        }
      }

      this.secondaryIndex = secondaryIndex;
      this.transactionAwareHTable = new TransactionAwareHTable(hTable);
      this.secondaryIndexTable = new TransactionAwareHTable(secondaryIndexHTable);
      this.transactionContext = new TransactionContext(transactionServiceClient,
                                                       transactionAwareHTable,
                                                       secondaryIndexTable);
    }

    public Result get(Get get) throws IOException {
      return get(Collections.singletonList(get))[0];
    }

    public Result[] get(List<Get> gets) throws IOException {
      try {
        transactionContext.start();
        Result[] result = transactionAwareHTable.get(gets);
        transactionContext.finish();
        return result;
      } catch (Exception e) {
        try {
          transactionContext.abort();
        } catch (TransactionFailureException e1) {
          throw new IOException("Could not rollback transaction", e1);
        }
      }
      return null;
    }

    public Result[] getByIndex(byte[] value) throws IOException {
      try {
        transactionContext.start();
        Scan scan = new Scan(value, Bytes.add(value, new byte[0]));
        scan.addColumn(secondaryIndexFamily, secondaryIndexQualifier);
        ResultScanner indexScanner = secondaryIndexTable.getScanner(scan);

        ArrayList<Get> gets = new ArrayList<Get>();
        for (Result result : indexScanner) {
          for (Cell cell : result.listCells()) {
            gets.add(new Get(cell.getValue()));
          }
        }
        Result[] results = transactionAwareHTable.get(gets);
        transactionContext.finish();
        return results;
      } catch (Exception e) {
        try {
          transactionContext.abort();
        } catch (TransactionFailureException e1) {
          throw new IOException("Could not rollback transaction", e1);
        }
      }
      return null;
    }

    public void put(Put put) throws IOException {
      put(Collections.singletonList(put));
    }

    public void put(List<Put> puts) throws IOException {
      try {
        transactionContext.start();
        ArrayList<Put> secondaryIndexPuts = new ArrayList<Put>();
        for (Put put : puts) {
          List<Put> indexPuts = new ArrayList<Put>();
          Set<Map.Entry<byte[], List<KeyValue>>> familyMap = put.getFamilyMap().entrySet();
          for (Map.Entry<byte [], List<KeyValue>> family : familyMap) {
            for (KeyValue value : family.getValue()) {
              if (value.getQualifier().equals(secondaryIndex)) {
                byte[] secondaryRow = Bytes.add(value.getQualifier(),
                                                DELIMITER,
                                                Bytes.add(value.getValue(),
                                                DELIMITER,
                                                value.getRow()));
                Put indexPut = new Put(secondaryRow);
                indexPut.add(secondaryIndexFamily, secondaryIndexQualifier, put.getRow());
                indexPuts.add(indexPut);
              }
            }
          }
          secondaryIndexPuts.addAll(indexPuts);
        }
        transactionAwareHTable.put(puts);
        secondaryIndexTable.put(secondaryIndexPuts);
        transactionContext.finish();
      } catch (Exception e) {
        try {
          transactionContext.abort();
        } catch (TransactionFailureException e1) {
          throw new IOException("Could not rollback transaction", e1);
        }
      }
    }
  }

文章转载自 开源中国社区 [http://www.oschina.net]

时间: 2024-10-22 19:14:40

Tephra —— HBase 全局一致性事务支持的相关文章

hbase-请问HBase的thrift客户端支持协处理器吗?

问题描述 请问HBase的thrift客户端支持协处理器吗? HBase,自己写的Endpoint协处理器通过Java可以访问,请问通过THrift C++客户端如何访问Endpoint协处理器

IBM BPM Advanced Integration Service配置事务支持

该实现演示了一些自动回滚功能,这些功能由 AIS 中基于 SCA 的管理与 WS-AT 协议协同提供.在第 2 部分中,您将为示例场景中的 Credit 和 Charge 操作配置事务支持,并实现两个事务 Web 服务(一个使用 .NET® 实现,另一个使用 JEE 实现). 本系列的第 2 部分将会介绍为示例场景中的 Credit 和 Charge 操作配置事务支持并实现两个事务 Web 服务的步骤:一个 .NET Web 服务,用于从机器 A 上的 SQL Server 上的 Bank1 扣

数据库事务系列-HBase行级事务模型

HBase是BigTable的开源实现,事务模型也与BigTable一脉相承 – 仅支持行级别的事务.虽然Jeff Dean大神在接受采访时公开承认目前在技术领域最后悔的事情就是没有在BigTable中加入跨行事务模型,以至于之后很多团队都在BigTable之上重复造各种各样的分布式事务轮子.这点笔者是认同的,现在确实有很多团队在HBase之上造了很多轮子(Tephra | Trafodian | Omid),试想如果这个工作做在了BigTable里面,这些团队的人是不是可以做更多其他有意义的事

青云QingCloud推出HBase集群服务 支持SQL等高级功能

为了更好地满足用户对大数据基础平台的需求,企业级基础云服务商青云QingCloud(qingcloud.com)日前宣布正式推出HBase集群服务,包含HBase数据库服务.HDFS分布式文件系统.Phoenix查询引擎三大组件.在原生HBase的基础上,QingCloud在配置的易用性.监控告警.在线伸缩等方面进行全面优化,并支持二级索引.SQL和JDBC API,以及完全ACID事务等高级功能,用户能够在2-3分钟内创建一个HBase集群,并能够在控制台直接修改配置文件并应用,极大地减轻了H

为ContentProvider添加数据库事务支持

介绍:数据库事务是由一组数据库操作序列组成,事务作为一个整体被执行. 事务的原子性:包含在其中的对数据库的操作序列最终要么全部执行,要么全部不执行.当全部执行时,事务对数据库的修改将生效:当全部不执行时,数据库维持原有的状态,不会被修改. 问题:最近在做一个从sdcard导入数据到数据库的功能,当导入失败时,数据库要恢复到导入前的状态.使用数据库事务处理能很好地满足到我们的需求. 我们知道Android平台上使用的sqlite数据库是支持事务处理功能的,实现的代码如下: [java] view

关于rabbitmq的事务支持问题

问题描述 查了很多资料,说是rabbitmq支持事务但是没想明白,这个事务是这么实现的比如我"支付系统"完成支付之后,要发消息给订单系统和商品系统那这个时候的事务应该怎么做呢假如,"订单系统"接受到消息后处理成功了,但是"商品系统"处理失败了这个时候怎么回滚"支付"结果和"订单"的处理呢 解决方案 本帖最后由 xiaqi1210 于 2014-08-02 15:34:36 编辑解决方案二: 自己顶一个~解决

win10安装(启动) .net framework 3.5组件出错:指定资源管理器中的事务支持未启动或已关闭

问题描述 看网上说的很多方法都试过了,1:使用命令提示符(错误6801,指定资源管理器中的事物支持未启动或以关闭)2:下载安装(错误同上)3:在windows中启动(错误同上)问题就是以上的这些,请大神帮我解答一下 解决方案 解决方案二:人在哪里?人在哪里解决方案三:人在哪里啊,大神在哪里

spring实现jdbctemplate添加事务支持示例_JSP编程

复制代码 代码如下: public interface JdbcTemplate extends JdbcOperations {public abstract void beginTranstaion(); public abstract void commit(); public abstract void rollback();} 复制代码 代码如下: public class JdbcTemplateImpl extends org.springframework.jdbc.core.J

【独家】一文读懂非关系型数据库(NoSQL)

前言 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL". 现代计算系统每天在网络上都会产生庞大的数据量.这些数据有很大一部分是由关系型数据库管理系统(RDBMSs)来处理,其严谨成熟的数学理论基础使得数据建模和应用程序编程更加简单. 但随着信息化的浪潮和互联网的兴起,传统的RDBMS在一些业务上开始出现问题.首先,对数据库存储的容量要求越来越高,单机无法满足需求,很多时候需要用集群来解决问题,而RDBMS由于要支持join,union等操作,一般不支持分