zoukankan      html  css  js  c++  java
  • HBase基础知识(4):批量处理操作

    之前我们学习过添加、检索和删除表中数据的操作了,不过都是基于单个实例或基于列表的操作。下边介绍一些API调用,可以批量处理跨多行的不同操作。

    事实上,许多基于列表的操作,如delete(List <Delete> deletes)或者get(List <Get> gets),都是基于batch()方法实现的。它们都是一些为了方便用户使用而保留的方法。如果你是新手,推荐使用batch()方法进行所有操作。
    下面的客户端API方法提供了批量处理操作。用户可能注意到这里引入了一个新的名为Row的类,它是Put、Get和Delete的祖先,或者是父类。

    void batch(List<Row> actions,Object[] results)
    throws IOException,InterruptedException
    Object [] batch(List<Row> actions)
    throws IOException,InterruptedException

    使用同样的父类允许在列表中实现多态,即放入以上3种不同的子类。这种调用跟之前介绍的基于列表的调用方法一样简单调用。
    请注意,不可以将针对同一行的Put和Delete操作放在同一个批量处理请求中,为了保证最好的性能,这些操作的处理顺序可能不同,但是这样会产生不可预料的结果。由于资源竞争,某些情况下用户会看到波动的结果。
    代码如下

    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.List;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.hbase.HBaseConfiguration;
    import org.apache.hadoop.hbase.client.Delete;
    import org.apache.hadoop.hbase.client.Get;
    import org.apache.hadoop.hbase.client.HTable;
    import org.apache.hadoop.hbase.client.Put;
    import org.apache.hadoop.hbase.rest.protobuf.generated.CellSetMessage.CellSet.Row;
    import org.apache.hadoop.hbase.util.Bytes;
    /*
    HBase批处理操作
    */
    public class HbaseBatch {
        private final static byte[] ROW1 = Bytes.toBytes("row1");
        private final static byte[] ROW2 = Bytes.toBytes("row2");
        private final static byte[] COLFMA1 = Bytes.toBytes("colfam1");
        private final static byte[] COLFMA2 = Bytes.toBytes("colfam2");
        private final static byte[] QUAL1 = Bytes.toBytes("qual1");
        private final static byte[] QUAL2 = Bytes.toBytes("qual2");
        private static byte[] COLFAM1;
    
        @SuppressWarnings("unchecked")
        public static void main(String[] args) throws IOException {
            Configuration conf = HBaseConfiguration.create();
            HTable table = new HTable(conf, "testtable");
            List<Row> batch = new ArrayList<Row>();
            Put put = new Put(ROW2);
            put.add(COLFMA2, QUAL1, Bytes.toBytes("val5"));
            batch.addAll((Collection<? extends Row>) put);
            Get get1 = new Get(ROW1);
            get1.addColumn(COLFAM1, QUAL1);
            batch.addAll((Collection<? extends Row>) get1);
            Delete delete = new Delete(ROW1);
            delete.deleteColumns(COLFAM1, QUAL2);
            batch.addAll((Collection<? extends Row>) delete);
            Get get2 = new Get(ROW2);
            get2.addFamily(Bytes.toBytes("BOGUS"));
            batch.addAll((Collection<? extends Row>) get2);
            Object[] results = new Object[batch.size()];
            try {
                //table.batch(batch,results);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    }
    

    从控制台上可以看到以下结果:

    Before batch call...
    KV:row1/colfam1:qual1/1/Put/vlen=4,Value:val1
    KV:row1/colfam1:qual2/2/Put/vlen=4,Value:val2
    KV:row1/colfam1:qual3/3/Put/vlen=4,Value:val3
    
    Result[0]:keyvalues=NONE
    Result[1]:keyvalues={row1/colfam1:qual1/1/Put/vlen=4}
    Result[3]:org.apache.hadoop.hbase.regionserver.NoSuchColumnFamilyExcepion:
    org.apache.hadoop.hbase.regionserver.NosuchColumnFamilyException:
     Column Family BOGUS dose not exist in...
    
    After batch call...
    KV:row1/colfam1:qual1/1/Put/vlen=4,Value: val1
    KV:row1/colfam1:qual3/3/Put/vlen=4,Value: val3
    KV:row2/colfam2:qual1/1308836506340/Put/vlen=4,Value:val5
    Error:org.apache.hadoop.hbase.client.RetireExhaustedWithDetailsException:
    Failed 1 action:NoSuchColumnFamilyException:1 time,servers with issues:10.0.0.43:60020,
    

    与之前的例子一样,在执行批处量处理之前,由于插入了测试行的数据,因此先打印出了测试行的相关输出。首先输出的是表的原内容,然后是示例代码产生的输出,最后输出的是操作以后表的内容。由输出结果可见,要删除的列被删除了,新添加的列也成功添加了。

    Get操作的结果需要观察输出结果的中间部分,即示例代码产生的输出。那些以Result[n](n从0到3)开头的输出是actions参数中对应操作的结果。示例中第一个操作是Put,对应的结果是一个空的Result实例,其中没有KeyValue实例。这是批量处理调用返回值的通常规则,它们给每个输入操作返回一个最佳匹配的结果,可能返回值如下表。

    结果 描述
    null 操作与远程服务器的通信失败
    EmptyResult Put与Delete操作成功后的返回结果
    Result Get操作成功的返回结果,如果没有匹配的行或列,会返回空的Result
    Throwable 当服务器端返回一个异常时,这个异常会按原样返回给客户端。用户可以使用这个异常检查哪里出了错,也许可以在自己的代码中自动处理异常

    当用户使用batch()功能时,Put实例不会被客户端写入缓冲区缓冲。batch()请求是同步的,会把操作直接发送到服务器端,这个过程没有什么延迟或其他中键操作,这与put()调用明显不同,所以请慎重挑选需要的方法。
    有两种不同的批量处理操作看起来非常相似。不同之处在于,一个需要用户输入包含返回结果的Object数组,而另一个由函数帮助用户创建这个数组。
    有两种不同的批量处理操作看起来非常相似。不同之处在于,一个需要用户输入包含返回结果的Object数组,而另一个由函数帮助创建这个数组。关键不同在于

    void batch(List<Row> actions,Object[] results)
     throws IOException,InterruptedException

    上面这个方法用户可以访问部分结果,而下面这个不行:

    Object batch(List<Row> actions)
     throws IOException,InterruptedException

    后面这个方法如果抛出异常的话,不会有任何返回结果,因为新结果数组返回之前,控制流就中断了。
    而之前的方法会先向用户提供的数组中填充数据,然后再抛出异常。下面试一下batch()方法特性的汇总。
    两种方法的共同点
    get、put和delete都支持。如果执行时出现问题,客户端将抛出异常并报告问题。它们都不使用客户端写缓冲区。
    void batch(acitons,results)
    能够访问成功操作的结果,同时也可以获取远程失败时的异常
    Object[] batch(acitons)
    只返回客户端异常,不能访问程序执行中的部分结果。
    **在检查结果之前,所有的批量处理操作都被执行了:即使用户收到一个操作的异常,其他操作都已执行了。不过,在最坏的情况下,可能所有操作都会返回异常。
    另外,批量处理可以感知暂时性错误,如NotServingRegionException会多次重试这个操作,用户可以通过调整hbase.client.retries.number配置项来增加或减少重试次数。**

  • 相关阅读:
    centos8上安装中文字符集
    python使用p12个人证书发送S/MIME加密,签名邮件
    linux 下如何获取 cpu 温度
    [官网]Apache Log4j2 最新版安全提示 2.17.0
    电子书下载:Beginning Windows Phone 7 Development
    沙发的含义
    电子书下载:Windows Phone 7 Developer Guide: Building connected mobile applications with Microsoft Silverlight
    电子书下载:The Rails 3 Way, 2nd Edition
    Enfocus Pitstop 7.52 汉化破解版安装
    电子书下载:Professional Flash Mobile Development: Creating Android and iPhone Applications
  • 原文地址:https://www.cnblogs.com/ainima/p/6331838.html
Copyright © 2011-2022 走看看