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等第三方应用实现。
推荐阅读
发表评论