本文讲解的HiveHBase整合意思是使用Hive读取Hbase中的数据。我们可以使用HQL语句在HBase表上进行查询、插入操作;甚至是进行Join和Union等复杂查询。此功能是从Hive 0.6.0开始引入的,详情可以参见HIVE-705。Hive与HBase整合的实现是利用两者本身对外的API接口互相进行通信,相互通信主要是依靠hive-hbase-handler-1.2.0.jar工具里面的类实现的。

使用

启动

我们可以使用下面命令启动Hive,使之拥有读取Hbase的功能,如果你的Hbase只有一台机器(single-node HBase server),可以使用下面命令启动hive client:

$HIVE_HOME/bin/hive --auxpath $HIVE_HOME/lib/hive-hbase-handler-1.2.0.jar,$HIVE_HOME/lib/hbase-0.92.0.jar,$HIVE_HOME/lib/zookeeper-3.3.4.jar,$HIVE_HOME/lib/guava-r09.jar --hiveconf hbase.master=www.iteblog.com:60000

如果你的Hbase master是通过Zookeeper维护的,那么你可以在启动Hive Client的时候指定Zookeeper的地址:

$HIVE_HOME/bin/hive --auxpath $HIVE_HOME/lib/hive-hbase-handler-1.2.0.jar,$HIVE_HOME/lib/hbase-0.92.0.jar,$HIVE_HOME/lib/zookeeper-3.3.4.jar,$HIVE_HOME/lib/guava-r09.jar --hiveconf hbase.zookeeper.quorum=www.iteblog.com

上面直接将Hbase相关的依赖加到启动命令行后面实在不太方便,我们可以在hive-site.xml进行配置:

<property
<name>hive.querylog.location</name
  <value>/home/iteblog/hive/logs</value
</property>
  
<property
  <name>hive.aux.jars.path</name
  <value>
      $HIVE_HOME/lib/hive-hbase-handler-1.2.0.jar,
      $HIVE_HOME/lib/hbase-0.92.0.jar,
      $HIVE_HOME/lib/zookeeper-3.3.4.jar,
      $HIVE_HOME/lib/guava-r09.jar
  </value
</property>
 
<property
  <name>hive.zookeeper.quorum</name
  <value>www.iteblog.com</value
</property

从Hive中创建HBase表

使用HQL语句创建一个指向HBase的Hive表

//Hive中的表名iteblog
CREATE TABLE iteblog(key int, value string)
//指定存储处理器
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
//声明列族,列名
WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")
//hbase.table.name声明HBase表名,为可选属性默认与Hive的表名相同,
//hbase.mapred.output.outputtable指定插入数据时写入的表,如果以后需要往该表插入数据就需要指定该值
TBLPROPERTIES ("hbase.table.name" = "iteblog", "hbase.mapred.output.outputtable" = "iteblog"); 

通过HBase shell可以查看刚刚创建的HBase表的属性

$ hbase shell
HBase Shell; enter 'help<RETURN>' for list of supported commands.
Version: 0.20.3, r902334, Mon Jan 25 13:13:08 PST 2010
hbase(main):001:0> list
iteblog
row(s) in 0.0530 seconds
hbase(main):002:0> describe "iteblog"
DESCRIPTION                                                            ENABLED                              
  {NAME => 'iteblog', FAMILIES => [{NAME => 'cf1', COMPRESSION =>      true                                
  'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536',
  IN_MEMORY => 'false', BLOCKCACHE => 'true'}]}
row(s) in 0.0220 seconds
  
hbase(main):003:0> scan "iteblog"
ROW                          COLUMN+CELL                                                                     
row(s) in 0.0060 seconds

插入数据

INSERT OVERWRITE TABLE iteblog SELECT * FROM pokes WHERE foo=98;

在HBase端查看插入的数据

hbase(main):009:0> scan "iteblog"
ROW                          COLUMN+CELL                                                                     
 98                          column=cf1:val, timestamp=1267737987733, value=val_98                           
1 row(s) in 0.0110 seconds

使用Hive中映射HBase中已经存在的表

创建一个指向已经存在的HBase表的Hive表

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

该Hive表一个外部表,所以删除该表并不会删除HBase表中的数据,有几点需要注意的是:

  1、建表或映射表的时候如果没有指定:key则第一个列默认就是行键
  2、HBase对应的Hive表中没有时间戳概念,默认返回的就是最新版本的值
  3、由于HBase中没有数据类型信息,所以在存储数据的时候都转化为String类型

多列及多列族的映射

如下表:value1和value2来自列族a对应的b c列,value3来自列族d对应的列e:

CREATE TABLE iteblog(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 iteblog SELECT foo, bar, foo+1, foo+2
FROM pokes WHERE foo=98 OR foo=100;

在Hbase中看起来是这样的:

hbase(main):014:0> describe "iteblog"
DESCRIPTION                                                             ENABLED                              
 {NAME => 'iteblog', FAMILIES => [{NAME => 'a', COMPRESSION => 'N true                                 
 ONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_M                                      
 EMORY => 'false', BLOCKCACHE => 'true'}, {NAME => 'd', COMPRESSION =>                                       
 'NONE', VERSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN                                      
 _MEMORY => 'false', BLOCKCACHE => 'true'}]}                                                                 
1 row(s) in 0.0170 seconds
hbase(main):015:0> scan "hbase_table_1"
ROW                          COLUMN+CELL                                                                     
 100                         column=a:b, timestamp=1267740457648, value=val_100                              
 100                         column=a:c, timestamp=1267740457648, value=101                                  
 100                         column=d:e, timestamp=1267740457648, value=102                                  
 98                          column=a:b, timestamp=1267740457648, value=val_98                               
 98                          column=a:c, timestamp=1267740457648, value=99                                   
 98                          column=d:e, timestamp=1267740457648, value=100                                  
2 row(s) in 0.0240 seconds

如果你在Hive中查询是这样的:

hive> select * from iteblog;
Total MapReduce jobs = 1
Launching Job 1 out of 1
...
OK
100 val_100 101 102
98  val_98  99  100
Time taken: 4.054 seconds

Hive Map类型在HBase中的映射规则

如下表:通过Hive的Map数据类型映射HBase表,这样每行都可以有不同的列组合,列名与map中的key对应,列值与map中的value对应

CREATE TABLE iteblog(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 iteblog SELECT map(bar, foo), foo FROM pokes
WHERE foo=98 OR foo=100;

cf为列族,其列名对应map中的bar,列值对应map中的foo。执行完上面的语句,在Hbase中看起来是这样的:

hbase(main):012:0> scan "iteblog"
ROW                          COLUMN+CELL                                                                     
 100                         column=cf:val_100, timestamp=1267739509194, value=100                           
 98                          column=cf:val_98, timestamp=1267739509194, value=98                             
2 row(s) in 0.0080 seconds

Hive中查询是这样的:

hive> select * from iteblog;
Total MapReduce jobs = 1
Launching Job 1 out of 1
...
OK
{"val_100":100} 100
{"val_98":98}   98
Time taken: 3.808 seconds

注意:由于map中的key是作为HBase的列名使用的,所以map中的key类型必须为String类型。以下映射语句会报错:

CREATE TABLE iteblog(key int, value map<int,int>)
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
"hbase.columns.mapping" = ":key,cf:"
);
FAILED: Error in metadata: java.lang.RuntimeException: MetaException(message:org.apache.hadoop.hive.serde2.SerDeException org.apache.hadoop.hive.hbase.HBaseSerDe: hbase column family 'cf:' should be mapped to map<string,?> but is mapped to map<int,int>)

因为map中的key必须是String,其最终需要变成HBase中列的名称。

支持简单的复合行键

如下:创建一张指向HBase的Hive表,行键有两个字段,字段之间使用~分隔

CREATE EXTERNAL TABLE iteblog(key struct<f1:string, f2:string>, value string)
ROW FORMAT DELIMITED
COLLECTION ITEMS TERMINATED BY '~'
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES (
  'hbase.columns.mapping'=':key,f:c1');

最后,使用Hive集成HBase表的需注意以下几点:

  1、对HBase表进行预分区,增大其MapReduce作业的并行度
  2、合理的设计rowkey使其尽可能的分布在预先分区好的Region上
  3、通过set hbase.client.scanner.caching设置合理的扫描缓存

Hive和HBase整合用户指南的更多相关文章

  1. 大数据工具篇之Hive与HBase整合完整教程

    大数据工具篇之Hive与HBase整合完整教程 一.引言 最近的一次培训,用户特意提到Hadoop环境下HDFS中存储的文件如何才能导入到HBase,关于这部分基于HBase Java API的写入方 ...

  2. Hadoop Hive与Hbase整合+thrift

    Hadoop Hive与Hbase整合+thrift 1.  简介 Hive是基于Hadoop的一个数据仓库工具,可以将结构化的数据文件映射为一张数据库表,并提供完整的sql查询功能,可以将sql语句 ...

  3. Hive(五):hive与hbase整合

    配置 hive 与 hbase 整合的目的是利用 HQL 语法实现对 hbase 数据库的增删改查操作,基本原理就是利用两者本身对外的API接口互相进行通信,两者通信主要是依靠hive_hbase-h ...

  4. Hive与Hbase整合

    Hive与Hbase整合 1.文档 Hive HBase Integration 2.拷贝jar文件 2.1.把Hbase的lib目录下面的jar文件全部拷贝到Hive的lib目录下面 cd /hom ...

  5. Hive和Hbase整合

    Hive只支持insert和delete操作,并不支持update操作,所以无法实施更新hive里的数据,而HBASE正好弥补了这一点,所以在某些场景下需要将hive和hbase整合起来一起使用. 整 ...

  6. hive与hbase整合过程

    实现目标 Hive可以实时查询Hbase中的数据. hive中的表插入数据会同步更新到hbase对应的表中. 可以将hbase中不同的表中的列通过 left 或 inner join 方式映射到hiv ...

  7. hive和hbase整合的原因和原理

    为什么要进行hive和hbase的整合? hive是高延迟.结构化和面向分析的: hbase是低延迟.非结构化和面向编程的. Hive集成Hbase就是为了使用hbase的一些特性.或者说是中和它们的 ...

  8. Hive篇---Hive与Hbase整合

     一.前述 Hive会经常和Hbase结合使用,把Hbase作为Hive的存储路径,所以Hive整合Hbase尤其重要. 二.具体步骤 hive和hbase同步https://cwiki.apache ...

  9. hive存储处理器(StorageHandlers)以及hive与hbase整合

    此篇文章基于hive官方英文文档翻译,有些不好理解的地方加入了我个人的理解,官方的英文地址为: 1.https://cwiki.apache.org/confluence/display/Hive/S ...

随机推荐

  1. python基本数据类型:字符串及其方法(二)

    格式化类 方法join() #join()用指定字符每间隔拼接字符串 name='miku' name1=' '.join(name) print(name1) 方法center() #center( ...

  2. vue2.0 axios前后端数据处理

    目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求,而大型项目都会使用 Vuex 来管理数据. 前言: 使用 cnpm 安装 axios cnpm install axios -S ...

  3. vue2.0+mint-ui资讯类顶导航和内容页联动实例(不是很完美)

    <template> <div> <div class="navbox"> <div class="nav"> ...

  4. 【Java】几种典型的内存溢出案例,都在这儿了!

    写在前面 作为程序员,多多少少都会遇到一些内存溢出的场景,如果你还没遇到,说明你工作的年限可能比较短,或者你根本就是个假程序员!哈哈,开个玩笑.今天,我们就以Java代码的方式来列举几个典型的内存溢出 ...

  5. List的扩容机制,你真的明白吗?

    一:背景 1. 讲故事 在前一篇大内存排查中,我们看到了Dictionary正在做扩容操作,当时这个字典的count=251w,你把字典玩的66飞起,其实都是底层为你负重前行,比如其中的扩容机制,当你 ...

  6. 7.SortSet排序集合类型操作

    Sort Set排序集合类型 (1)介绍 和set一样sorted set也是string类型元素的集合,不同的是每个元素都会关联一个权.通过权值可以有序的获取集合中的元素 该Sort Set类型适合 ...

  7. 赛艇表演 51nod提高组模拟试题

    AC通道 题目描述 小明去某个地区观看赛艇比赛,这个地区共有n个城市和m条道路,每个城市都有赛艇比赛,在第i个 城市观看赛艇表演的价钱为ai, 去其他城市观看也需要支付赛艇表演的价格.任意两个城市之间 ...

  8. 分享按钮(QQ,微信,微博等)移入动画效果

    ps:最近写的很多博客都是在以前在项目里写过的,之所以现在写出来,最大的目的就是希望自己以后用到的时候比较容易找,而且现在再写一遍,有助于加深印象! 很简单的效果,说先实现方式: 1.图标来自 阿里巴 ...

  9. Java实现 蓝桥杯 算法训练 排序

    算法训练 排序 时间限制:1.0s 内存限制:512.0MB 问题描述 编写一个程序,输入3个整数,然后程序将对这三个整数按照从大到小进行排列. 输入格式:输入只有一行,即三个整数,中间用空格隔开. ...

  10. Java实现 蓝桥杯VIP 算法提高 进制转换

    算法提高 进制转换 时间限制:1.0s 内存限制:256.0MB 问题描述 程序提示用户输入三个字符,每个字符取值范围是0-9,A-F.然后程序会把这三个字符转化为相应的十六进制整数,并分别以十六进制 ...