1. 创建HBASE表

create 'bd:od_t1','cf'

需要注意的:

一定要指定压缩格式COMPRESSION=>'SNAPPY',否则写入Hbase的数据会很大 如果数据量巨大(总量超1亿)要先预分区,预分区可以直接指定,比如SPLITS => ['0|', '1|', '2|'],若预分区数量大可先写入一个文件中再使用{SPLITS_FILE => '/data/zp_dw/init/hbase/split.txt'}进行分区。预分区直接会影响到写入的效率,合理的分区能带来5倍以上效率的提升 预分区是以Hbase中表的Rowkey进行的分区,一般而言如果rowkey开头是数字,那么我们会以数字开头,并以|结尾来作为预分区的边界。 若不需要多版本存储,可以指定VERSIONS=>1版本号为1.

2. 创建 hive 外部表

-- hbase 机器

set hbase.zookeeper.quorum="192.12.141,192.12.142,192.12.143";

-- hive 的库名

use ods ;

--hive 和 HBASE 映射表名

ods_hbase_1

-- 原始数据源表名

ods_1

-- HBASE 表名

bd:od_t1

CREATE EXTERNAL TABLE if not exists ods.ods_hbase_1

(

key string comment data_day|id|logid ',

data_day string comment ' 时间 ',

id string comment 'id',

name string comment ' 姓名 ',

logid string comment ' 日志 id'

)

STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

WITH SERDEPROPERTIES

( \" hbase.columns.mapping \" = \"

:key,

cf:data_day,

cf:id,

cf:name,

cf:logid \"

)

TBLPROPERTIES( \" hbase.table.name \" = \" bd:od_t1 \" );

需要注意的

hive表应为外部表,创建时加external关键字 指定存储为stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' 需要指定hive字段与Hbase列的mapping,"hbase.columns.mapping" = ":key, cf1:data_day, cf1:, name...... 指定Hbase表的属性信息。

3. 往映射表插入数据

Hive映射Hbase表,主要用来向Hbase推送数据。建立映射后向Hive表写入数据会实时写到Hbase对应的表中。写入时可设置参数加快写入速度。比如:

SET hive.hbase.bulk=true;

set hbase.zookeeper.quorum="192.12.141,192.12.142,192.12.143";

insert into table ods.ods_hbase_1

select 

concat(data_day,"|",id,"|",logid) as key,

data_day,

id,

name,

logid

from ods.ods_1;

需要注意:合理的参数会加快写入速度,比如:

set hive.hbase.bulk=true;

set hive.hbase.wal.enabled=false;

实际使用中HBase的优势和问题

先说优势,在明确rowkey的情况下,随机存取海量数据无压力,而且可根据数据大小自动水平扩展,数据量不会成为瓶颈。底层基于HDFS构建,数据都有副本冗余存储,可靠性和高可用都有保证。

遇到的问题

我们将Hive映射至Hbase表,写入数据后。发现某些数据行中会多出一个空列,名称为_0。因为是随机出现,且该数据只通过Hive写入,所以一直怀疑是Hive的bug。近期频繁发生,决定彻底解决一下,下载了hive的源码,其中包org.apache.hadoop.hive.hbase下有写入Hbase的相关操作,查看并未发现有写空列的操作,Hive写Hbase是根据建表是的列映射信息进行的。空列与hive没有关系。继续梳理于hbase有关的服务,发现Phoenix比较可疑,当时为了查询方面,安装了Phoenix,并建表与hbase关联。查看Phoenix文档,其中有一句The empty or dummy KeyValue (with a column qualifier of _0) is needed to ensure that a given column is available for all rows.,原因定位,去除Phoenix与hbase映射,问题解决。

 

当然问题也不少:

首要的是二级索引问题,HBase并未原生支持二级索引,第三方Phoenix等实现的又并不完善,使用有很大的局限。比如:用户行为轨迹数据,rowkey的组成“用户_id+日期+本行hash值”,这样前台应用可按用户id非常快的找到该用户的所有轨迹数据,但如果我们要按日期查找就无能为力了,只有扫描全表百亿数据才行,当数据按天写入,想核验某一日期写入的数据是否正确,就非常麻烦。其次Hbase原生只支持API访问,并没有sql接口,对于使用来说还是很复杂,需要了解Hbase的好多概念才能正确使用。对于数据的聚合,目前Hbase是无能为力,只能通过基于Hbase的Kylin、Phoenix等第三方应用实现。

推荐阅读

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: