原创干货 | Hive与HBase的集成实践

Posted 天善大数据

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了原创干货 | Hive与HBase的集成实践相关的知识,希望对你有一定的参考价值。

Hive与HBase集成实践

大数据平台搭建 hive-2.0.0 hbase 1.1.3

环境说明

  • CentOS 6.7

  • Hadoop 2.7.2

  • Hive 2.0.0

  • HBase 1.1.3

一、具体步骤

    1. 拷贝jar包

  1. 首先删除$HIVE_HOME/lib下HBase和ZooKeeper相关的jar包

  2. 然后重新拷贝$HBASE_HOME/lib下的HBase和ZooKeeper相关的jar包至Hive下

    2. 在Hive的类路径中添加一些这些jar包

有两种方式向Hive的类路径添加jar包:

  • 修改hive-site.xml中hive.aux.jars.path的值

<property>
   <name>hive.aux.jars.path</name>
   <value>/opt/hive-2.0.0/lib/guava-14.0.1.jar,/opt/hive-2.0.0/lib/zookeeper-3.4.6.jar,/opt/hive-2.0.0/lib/hive-hbase-handler-2.0.0.jar,/opt/hive-2.0.0/lib/hbase-common-1.1.3.jar,/opt/hive-2.0.0/lib/hbase-server-1.1.3.jar</value>
   <description>The location of the plugin jars that contain implementations of user defined functions and serdes.</description>
 </property>
  • 在$HIVE_HOME/conf/下新建.hiverc文件,加入下列语句:

add jar /opt/hbase-1.1.3/lib/htrace-core-3.1.0-incubating.jar;
add jar /opt/hbase-1.1.3/lib/hbase-common-1.1.3.jar;
add jar /opt/hbase-1.1.3/lib/hbase-hadoop2-compat-1.1.3.jar;
add jar /opt/hive-2.0.0/lib/hive-metastore-2.0.0.jar;
add jar /opt/hbase-1.1.3/lib/hbase-server-1.1.3.jar;
add jar /opt/hbase-1.1.3/lib/hbase-client-1.1.3.jar;
add jar /opt/hbase-1.1.3/lib/hbase-protocol-1.1.3.jar;
add jar /opt/hive-2.0.0/hcatalog/share/hcatalog/hive-hcatalog-core-2.0.0.jar;
add jar /opt/hive-2.0.0/lib/datanucleus-core-4.1.6.jar;
add jar /opt/hive-2.0.0/lib/datanucleus-api-jdo-4.2.1.jar;
add jar /opt/hive-2.0.0/lib/datanucleus-rdbms-4.1.7.jar;
add jar /opt/hive-2.0.0/lib/hive-cli-2.0.0.jar;
add jar /opt/hive-2.0.0/lib/hive-hbase-handler-2.0.0.jar;

hive在执行命令前会先读取.hiverc的文件中的内容

启动Hive 和 HBase即可使用,具体示例如第3节。


二、Hive集成HBase的原理

1. Storage Handler

  • 基本原理 
    Hive与HBase集成的实现是利用了这两者本身对外提供的API进行相互通信,这种相互通信是通过$HIVE_HOME/lib/hive-hbase-handler-2.0.0.jar工具类实现的。通过HBaseStorageHandler,Hive可以获取到Hive表所对应的HBase表名,列簇和列,InputFormat、OutputFormat类,创建和删除HBase表等。

  • 访问 
    Hive访问HBase中HTable的数据,实质上是通过MR读取HBase的数据,而MR是使用HiveHBaseTableInputFormat完成对表的切分,获取RecordReader对象来读取数据的。 
    对HBase表的切分原则是一个Region切分成一个Split,即表中有多少个Regions,MR中就有多少个Map; 
    读取HBase表数据都是通过构建Scanner,对表进行全表扫描,如果有过滤条件,则转化为Filter。当过滤条件为rowkey时,则转化为对rowkey的过滤;Scanner通过RPC调用RegionServer的next()来获取数据。

2. 使用

插入大量数据可能会由于WAL负载导致速度很慢,可以通过在插入数据之前做如下设置:

set hive.hbase.wal.enabled=false;

但是关闭WAL可能会使HBase发生错误时出现数据丢失,所以建议只有在你已有其他数据恢复策略时才使用这种设置。

若想使Hive可以访问已存在的HBase表,可以使用下面的语句创建这样的Hive表:

CREATE EXTERNAL TABLE hbase_table_2(key int, value string) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val")
TBLPROPERTIES("hbase.table.name" = "xyz", "hbase.mapred.output.outputtable" = "xyz");

hbase.columns.mapping是必须的,这将会和已存在的HBase表的列族进行验证,而hbase.table.name和hbase.mapred.output.outputtable是可选的。当在Hive中删除此表时,并不影响HBase中对应的表。


3. 字段映射

控制HBase字段和Hive之间的映射有两种SERDEPROPERTIES:

  • hbase.columns.mapping

  • hbase.table.default.storage.type,可以是string(default)或binary中的任一个,指定这个选项只有在Hive 0.9之后可使用.

目前所支持的字段映射多少是有些难处理或存在约束的:

  • 对于每一个Hive字段,表的创建者必须用逗号分隔的字符串(hbase.columns.mapping)指定对应的入口(Hive表有n个字段,则该字符串得指定n个入口),在各个入口之间不能由空格(因为空格会被解析成字段名中的一部分)。

  • 映射入口必须是以下两者之一:行健或’列族名:[列名][#(binary|string)]’ 

    • 如果没有指定类型,则直接使用hbase.table.default.storage.type的值

    • 合法值的的前缀也是合法的(例如#b表示#binary)

    • 如果指定某字段为binary,则对应的HBase中的单元格则应该是HBase的Bytes类的内容组成

  • 必须要有确切的行健映射

  • 如果没有指定列名,则默认使用Hive的字段名作为HBase中的列名

三、 示例

1. 多列和列族

Hive表中的3个字段与HBase中的2个列族,其中2个Hive字段(value1和value2)对应到1个HBase列族(列族a,列b和c),另1个Hive字段(e)对应到另1个HBase列族的单个列(d)。Hive建表SQL如下:

CREATE TABLE hbase_table_1(key int, value1 string, value2 int, value3 int) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
"hbase.columns.mapping" = ":key,a:b,a:c,d:e"
);

INSERT OVERWRITE TABLE hbase_table_1 SELECT foo, bar, foo+1, foo+2
FROM pokes WHERE foo=98 OR foo=100;

此表在HBase中是这个样子的:

hbase(main):006:0> describe 'hive_hbase.hbase_table_2'
Table hive_hbase.hbase_table_2 is ENABLED                                  
hive_hbase.hbase_table_2                                                    
COLUMN FAMILIES DESCRIPTION                                                
{NAME => 'a', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', K
EEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER
'
, COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSI
ZE => '65536', REPLICATION_SCOPE => '0'}                                    
{NAME => 'd', BLOOMFILTER => 'ROW', VERSIONS => '1', IN_MEMORY => 'false', K
EEP_DELETED_CELLS => 'FALSE', DATA_BLOCK_ENCODING => 'NONE', TTL => 'FOREVER
'
, COMPRESSION => 'NONE', MIN_VERSIONS => '0', BLOCKCACHE => 'true', BLOCKSI
ZE => '65536', REPLICATION_SCOPE => '0'}                                    
2 row(s) in 0.0190 seconds

hbase(main):007:0> scan'hive_hbase.hbase_table_2'
ROW                  COLUMN+CELL                                            
100                 column=a:b, timestamp=1464598569847, value=val_100    
100                 column=a:c, timestamp=1464598569847, value=101        
100                 column=d:e, timestamp=1464598569847, value=102        
98                  column=a:b, timestamp=1464598569847, value=val_98      
98                  column=a:c, timestamp=1464598569847, value=99          
98                  column=d:e, timestamp=1464598569847, value=100        
2 row(s) in 0.0200 seconds

再回到Hive中查询此表:

hive> select * from hbase_table_2;
OK
100 val_100 101 102
98  val_98  99  100
Time taken: 0.298 seconds, Fetched: 2 row(s)

2. Hive的Map字段与HBase列族

如何使用Hive的Map数据类型访问列族,每行可以有很多不同的列,而列名正好对应到Map类型字段的Keys,而列值正好对应到Map类型字段的Map值。Hive建表SQL如下:

CREATE TABLE hbase_table_3(value map<string,int>, row_key int) 
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
"hbase.columns.mapping" = "cf:,:key"
);
INSERT OVERWRITE TABLE hbase_table_3 SELECT map(bar, foo), foo FROM pokes
WHERE foo=98 OR foo=100;

这个表在HBase中是长这个样子:

hbase(main):009:0> scan'hive_hbase.hbase_table_3'
ROW                  COLUMN+CELL                                            
100                 column=cf:val_100, timestamp=1464600230691, value=100  
98                  column=cf:val_98, timestamp=1464600230691, value=98    
2 row(s) in 0.0220 seconds

再回到Hive中查询此表:

hive> select * from hbase_table_3;
OK
{"val_100":100} 100
{"val_98":98}   98
Time taken: 0.163 seconds, Fetched: 2 row(s)


火爆参团:天善学院联合Mars老师推出《对话大数据系列技术 从破冰到精进》正在火热参团中,已是冰点价了喔~

参团方式:扫描二维码 | 阅读原文

以上是关于原创干货 | Hive与HBase的集成实践的主要内容,如果未能解决你的问题,请参考以下文章

全网最详细的hive-site.xml配置文件里如何添加达到Hive与HBase的集成,即Hive通过这些参数去连接HBase(图文详解)

spark集成hbase与hive数据转换与代码练习

HBase与Hive集成

HBase与Hive的集成操作

HBase与Hive的集成操作

HBase