zoukankan      html  css  js  c++  java
  • 【hbase】——bulk load导入数据时value=x00x00x00x01问题解析

    一、存入数据类型

    Hbase里面,rowkey是按照字典序进行排序。存储的value值,当用filter进行数据筛选的时候,所用的比较算法也是字典序的。

    1、当存储的value值是float类型的时候,录入数据可以录入,但是读取出来的数据会存在问题会出问题

    例如:

    存入数据的代码:

    p = new Put(Bytes.toBytes(“66”));

    p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Float.valueOf(533.0)));

    ...

    在hbase shell里面取出的数据:

    hbase(main):007:0> get 'DATA‘, '66'
    COLUMN                CELL
    value:null           timestamp=668, value=Dx05@x00
    1 row(s) in 0.1100 seconds
    可以看到取出来的value值是不可读的。

    在java程序里面则没有返回结果,如果想强制类型转换读取这个数据,则会报错,说格式错误:

      try {
       Result rr = table.get(g);
       for (KeyValue kvv : rr.raw()) {
    float f = Float.parseFloat(new String(kvv.getValue()));
        System.out.println(f);
        tempList.add(kvv.getTimestamp() + "," + new String(kvv.getValue()));
       }
      } catch (IOException e) {
       e.printStackTrace();
      }

    java.lang.NumberFormatException: For input string: "D@"

    根据hbase都是按照字典序进行排序的前提,(字典序多少针对字符串的),可以推测hbase不支持float类型数据的存储

    2、如果把录入数据改成int型

    存入数据的代码:

    p = new Put(Bytes.toBytes(“66”));

    p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Integer.valueOf(533.0)));

    ...

    取出的数据

    hbase(main):007:0> get 'DATA‘, '66'

    COLUMN CELL
    value:null timestamp=668, value=x00x00x00x00x00x00x02x15
    1 row(s) in 1.4510 seconds

    在java程序里面则没有返回结果,当试图把取出的数据强制类型转换的时候,同样报错

    3、 如果把录入数据改成long型

    存入数据的代码:

    p = new Put(Bytes.toBytes(“66”));

    p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes(Long.valueOf(533.0)));

    ...

    取出的数据

    hbase(main):007:0> get 'DATA‘, '66'

    COLUMN                CELL
    value:null           timestamp=668, value=x00x00x00x00x00x00x02x15
    1 row(s) in 1.4510 seconds

    同样不可读

    4、如果把录入value格式改成String类型,则正常

    存入数据的代码:

    p = new Put(Bytes.toBytes(“66”));

    p.add(Bytes.toBytes("value"),Bytes.toBytes("null"), (Long.valueOf(“668”) ), Bytes.toBytes("533.0"));

    ...

    取出的数据

    hbase(main):007:0> get 'DATA‘, '66'

    COLUMN                CELL
    value:null           timestamp=668, value=533.0
    1 row(s) in 0.8500 seconds

    在java程序里面也有可用的结果

    通过上述测试说明,hbase现在只支持String类型数据的存取

    二、 小的注意点

    1、取value的时候一定要用 new String(kv[i].getValue())的格式

        System.out.println(kv[i].getValue().toString());     错误
        System.out.println(new String(kv[i].getValue()));    正确

    2、用完ResultScanner 后一定要记得关掉:resultScanner.close();

    3、当录入的数据已经使用了String类型

    那么,进行比较的时候也要使用String类型。例如下面使用float类型的filter,则不会对结果产生任何影响

      Filter filter = new SingleColumnValueFilter(
                 Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(Float.valueOf((float) 5.0)));
      scan.setFilter(filter); 
    如果换成

      Filter filter = new SingleColumnValueFilter(
                 Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes("5.0"));

    scan.setFilter(filter);

    则会会结果产生影响,但是需要注意的是,这里的设置方式也是错误的

    追踪原因:

    hbase关于比较的相关源码如下:

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

     
      public static int compareTo(final byte [] left, final byte [] right) {
        return compareTo(left, 0, left.length, right, 0, right.length);
      }

     
      public static int compareTo(byte[] buffer1, int offset1, int length1,
          byte[] buffer2, int offset2, int length2) {
        // Bring WritableComparator code local
        int end1 = offset1 + length1;
        int end2 = offset2 + length2;
        for (int i = offset1, j = offset2; i < end1 && j < end2; i++, j++) {
          int a = (buffer1[i] & 0xff);
          int b = (buffer2[j] & 0xff);

          if (a != b) {
            return a - b;
          }
        }
        return length1 - length2;
      }

    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    疑问:下面long型筛选,返回的结果并没有value值,但是,结果的数据条数却会发生变化,即使针对这个特定的时间戳读取数据也没有结果数据(曾试图用scan确定了那个rowkey的那个列簇的那个列的那个时间戳,任何通过这些信息用get进行取值,但是也不能返回value值),为什么结果的条数会发生变化呢?

    1、filter

    (1)录入的value是long型

    如果想设置成数值型比较,则要进行数据类型设置,如下

    Filter filter = new SingleColumnValueFilter(
                 Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(Long.valueOf(5)));
      scan.setFilter(filter);

    resultScanner = table.getScanner(scan);

    结果是:

    rowkey                         列簇:列名 时间戳   value

    115404869300388065  value:null     27

    115404869300388065  value:null     26

    但是如果设置成字符串行,如下:

    Filter filter = new SingleColumnValueFilter(
    Bytes.toBytes("value"),Bytes.toBytes("null") , CompareOp.LESS,Bytes.toBytes(”5“));
    scan.setFilter(filter);

    resultScanner = table.getScanner(scan);

    则返回的是按照字典序比较的结果(ps:rowkey是按照字典序排列的,10000比2 “小”)

    115404869300388065  value:null  27

    115404869300388065  value:null  3

    115404869300388065  value:null  2

    115404869300388065  value:null  1

    细心的话可以发现输出的几个也是按照降序的顺序排列的

  • 相关阅读:
    TVM量化代码解析
    如何在 GPU 上优化卷积
    全文翻译(全文合集):TVM: An Automated End-to-End Optimizing Compiler for Deep Learning
    全文翻译(四) TVM An Automated End-to-End Optimizing Compiler
    全文翻译(三) TVM An Automated End-to-End Optimizing Compiler
    全文翻译(二): TVM: An Automated End-to-End Optimizing Compiler for Deep Learning
    全文翻译(一):TVM: An Automated End-to-End Optimizing Compiler for Deep Learning
    pytorch使用gpu加速的方法
    springboot的实践1
    带你玩转stackOverflow-3
  • 原文地址:https://www.cnblogs.com/zhengrunjian/p/4535273.html
Copyright © 2011-2022 走看看