【问题标题】:Hbase shell: value is cutHbase shell:值被切割
【发布时间】:2012-05-22 02:48:05
【问题描述】:

我有一个名为“mytable”的 hbase 表,其中只有一个列族“default”和一个限定符“details”。

现在我做这个查询:

get 'mytable', 'test'

并且结果的值被截断。它应该是一个数字(长):

COLUMN                      CELL                                                                           
default:details            timestamp=1337007859494, value=\x00\x00\x00\x00\x00\x00\xDFH                   
1 row(s) in 0.0360 seconds

为什么我只看到前七个字节?我怎样才能看到完整的价值?

如果我要求一些价值很小的东西,它会起作用。但大值是不完整的。

【问题讨论】:

  • 你是如何插入值的?
  • 这些值由 Java 编写的 Map Reduce 作业插入。
  • 您能否尝试让 MR 作业在插入之前打印该值,以确保不会插入错误的值。另外,尝试使用 java 文件读取值,以确保这不是 jruby shell 的问题。
  • 好的,我这样做了。请参阅第一个答案。

标签: hbase


【解决方案1】:

您的问题的简短答案是:

get 'mytable', 'test', {COLUMN => 'default:details:toLong'}

Long :) 版本:

如果你在 HBase 的 shell 中输入 help 'get',你会发现:

Besides the default 'toStringBinary' format, 'get' also supports custom formatting by
column.  A user can define a FORMATTER by adding it to the column name in the get
specification.  The FORMATTER can be stipulated: 

 1. either as a org.apache.hadoop.hbase.util.Bytes method name (e.g, toInt, toString)
 2. or as a custom class followed by method name: e.g. 'c(MyFormatterClass).format'.

Example formatting cf:qualifier1 and cf:qualifier2 both as Integers: 
  hbase> get 't1', 'r1' {COLUMN => ['cf:qualifier1:toInt',
    'cf:qualifier2:c(org.apache.hadoop.hbase.util.Bytes).toInt'] } 

【讨论】:

    【解决方案2】:

    所有 8 个字节的 long 都在该字符串中:

    \x00\x00\x00\x00\x00\x00\xDFH
    

    这样更容易看到:

    \x00 \x00 \x00 \x00 \x00 \x00 \xDF H
    

    前 6 个字节是 0(十六进制 \x00),下一个是 223(十六进制 \xDF),最后一个是 ASCII H(\x48),这使得你的十进制长 57,160。 HBase 的值只是字符数组,不识别类型,因此 shell 将所有不可打印的 ASCII 字节作为十六进制转义,只留下那些并不总是最清晰的字节。

    【讨论】:

    • 你是怎么从之前的57160到的?
    • 他的数字是0xDF48,换算成十进制是57160:google.com/…
    【解决方案3】:

    尝试让 MR 作业在插入之前打印值,以确保不会插入错误的值。

    还可以尝试使用 java 文件读取值,以确保这不是 jruby shell 的问题。

    【讨论】:

      【解决方案4】:

      好的,我写了一个小 Java 来告诉我价值。这行得通。愚蠢的 hbase shell。

      import java.io.IOException;
      
      import org.apache.hadoop.conf.Configuration;
      import org.apache.hadoop.hbase.HBaseConfiguration;
      import org.apache.hadoop.hbase.client.Get;
      import org.apache.hadoop.hbase.client.HTable;
      import org.apache.hadoop.hbase.client.Result;
      import org.apache.hadoop.hbase.util.Bytes;
      
      
      public class HBaseGet {
      
      public static void main(String[] args) throws IOException {
      
          if(args.length < 4) {
              throw new IOException("Parameters: table rowid columnFamily qualifier");
          }
      
          assert args.length >= 4;
      
          String tablename = args[0];
          byte[] rowid = Bytes.toBytes(args[1]);
          byte[] family = Bytes.toBytes(args[2]);
          byte[] qualifier = Bytes.toBytes(args[3]);
      
          Configuration config = HBaseConfiguration.create();
          HTable table = new HTable(config, tablename);
      
          Get get = new Get(rowid);
          Result result = table.get(get);
      
          if (result != null) {
              byte[] value = result.getValue(family, qualifier);
              String valueStr = Bytes.toString(value);
      
              // convert bytes to long
              long valueLong = 0L;
              for (int i = 0; i < value.length; i++)
              {
                  valueLong = (valueLong << 8) + (value[i] & 0xff);
              }
      
              System.out.println("================");
              System.out.println("String: "+valueStr);
              System.out.println("Long: "+valueLong);
              System.out.println("================");
          }
      
      }
      
      }
      

      【讨论】:

      • 我喜欢 cftarnas 的回答,因为它确实回答了我的问题。编写这个脚本并不是一个好的解决方案。
      • 有道理,它回答了真正的问题。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-01
      相关资源
      最近更新 更多