填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题

公司有个系统定期向hbase插入数据,记录系统日志。有个字段需要存储long类型的时间戳,具体向hbase插入数据的代码意思大概如下:

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题            put.add(Bytes.toBytes(family),Bytes.toBytes(column),Bytes.toBytes(new Date().getTime())); 
            table.put(put);  
            table.close();  

构造put对象,插入hbase,先插入一条数据如下:

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 hbase(main):042:0> scan 'test_put'
ROW                                      COLUMN+CELL                                                                                                         
  111111                                  column=cf:time, timestamp=1511271122413, value=\x00\x00\x01_\xDE\xB9~\x15                                           
1 row(s) in 0.0160 seconds

可以看出来,time字段的值是乱码的,因为hbase默认将值先转为字节码存储。对于long类型的数据,java查询时需要再通过 Bytes.toLong()转换:

我们需要对这张表数据进行分析,方案是通过impala-sql进行,所以需要先在hive端创建外部表:

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 hive> create external table test_put (key string,time bigint) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

with serdeproperties ("hbase.columns.mapping"=":key,cf:time") tblproperties("hbase.table.name"="test_put");

创建好外部表后,在impala里查询

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 [mp.isc.com:21000] > select * from test_put;
Query: select * from test_put
Query submitted at: 2017-11-21 21:50:49 (Coordinator: http://hdapp1:25000)
Query progress can be monitored at: http://hdapp1:25000/query_plan?query_id=954c50a8cdaa9758:d26909f400000000
+--------+------+
| key    | time |
+--------+------+
| 111111 | NULL |
+--------+------+

奇怪的是time字段为null

单独查询time字段报错如下:

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 [mp.isc.com:21000] > select time from test_put;
Query: select time from test_put
Query submitted at: 2017-11-21 21:51:45 (Coordinator: http://hdapp1:25000)
Query progress can be monitored at: http://hdapp1:25000/query_plan?query_id=a34523e2be23b38d:1dd9009d00000000
+------+
| time |
+------+
| NULL |
+------+
WARNINGS: Error converting column cf:time: '_޹~' TO BIGINT

提示不能转换为bigint,可是hbase那边明明是按照long类型 再getBytes插入的,这就很奇怪了,仔细一想应该是hive那边不知道hbase是按long类型存的,所以问题应该出在hive建外部表那边,遂去查阅hive官方文档。

    在 hive  hbase integration 集成这段,有这么一段话

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题

意思是要在hbase的列后面添加  #b 以指明不是简单的string。好,我们改下hive建表语句,重新建表

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 hive> create external table test_put (key string,time bigint) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties ("hbase.columns.mapping"=":key,cf:time#b") tblproperties("hbase.table.name"="test_put");


再查询:

填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题 [mp.isc.com:21000] > select * from test_put;
Query: select * from test_put
Query submitted at: 2017-11-21 22:07:30 (Coordinator: http://hdapp1:25000)
Query progress can be monitored at: http://hdapp1:25000/query_plan?query_id=fa4c7e7e44eff4fa:875ee6800000000
+--------+---------------+
| key    | time          |
+--------+---------------+
| 111111 | 1511270219285 |
+--------+---------------+

大功告成。填坑之路:记一次hive外部表查询hbase的long类型数据出现乱码问题