hive与hbase集成
http://blog.csdn.net/vah101/article/details/22597341
这篇文章最初是基于介绍HIVE-705。这个功能允许Hive QL命令访问HBase表,进行读(select)、写(insert)操作。它甚至可以基于join、union操作对hbase表和hive原生的表进行混合访问。
这个功能还在不断的完善中,欢迎提出建议。
存储handler
在开始介绍之前,首先请阅读StorageHandlers,对存储处理程序的框架有个初步的认识,可以帮助读者理解HBase集成。
使用方法
这个存储处理程序被编译成一个独立的模块, hive-hbase-handler-x.y.z.jar,必须与guava、zookeeper的jar包被hive的客户端程序识别到(通过--auxpath指定)。也需要正确的配置hbase master的ip地址,保证能够与hbase连接。启动HBase集群的方法,请见the HBase documentation。
这里有个例子是使用源代码编译环境的命令行,连接到一个单结点的HBase server。(注意,jar包的位置在hive 0.9.0版本以后发生了变化,对于早期的版本,要注意这些变化)
$HIVE_SRC/build/dist/bin/hive --auxpath $HIVE_SRC/build/dist/lib/hive-hbase-handler-0.9.0.jar,$HIVE_SRC/build/dist/lib/hbase-0.92.0.jar,$HIVE_SRC/build/dist/lib/zookeeper-3.3.4.jar,$HIVE_SRC/build/dist/lib/guava-r09.jar -hiveconf hbase.master=hbase.yoyodyne.com:60000
以下则是一个连接到一个分布式的HBase集群的例子,通过一个3结点的zookeeper集群来确定HBase的master结点:
$HIVE_SRC/build/dist/bin/hive --auxpath $HIVE_SRC/build/dist/lib/hive-hbase-handler-0.9.0.jar,$HIVE_SRC/build/dist/lib/hbase-0.92.0.jar,$HIVE_SRC/build/dist/lib/zookeeper-3.3.4.jar,$HIVE_SRC/build/dist/lib/guava-r09.jar -hiveconf hbase.zookeeper.quorum=zk1.yoyodyne.com,zk2.yoyodyne.com,zk3.yoyodyne.com
这个处理程序需要Hadoop 0.20版本以上,当前只测试过基于hadoop-0.20.x、hbase-0.92.0和zookeeper-3.3.4的情况。如果你不是使用hbase-0.92.0,你将需要重新编译与hbase的jar包相对应的handler处理程序,并且修改上文中提到的相应的--auxpath命令行参数。使用不对应的hbase jar包编译,将会导致连接错误异常,比如 MasterNotRunningException,这是因为hbase的RPC协议经常随版本更新发生变化。
为了创建一个新的可供hive管理的HBase表,需要使用“ STORED BY clause on CREATE TABLE”命令:
- CREATE TABLE hbase_table_1(key int, value string)
- STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
- WITH SERDEPROPERTIES ("hbase.columns.mapping" = ":key,cf1:val")
- TBLPROPERTIES ("hbase.table.name" = "xyz");
这个hbase.columns.mapping属性是必需的,将会被下一段的所解释。hbase.table.name属性是可选的,它控制了HBase中创建的表的名字,并且允许其与hive表使用不同的名字。在这个例子中欧,在hive中的表名是hbase_table_1,在HBase中,则被命名为xyz。如果没有特别标名,hive与hbase表将会使用相同的名字。
在以上命令执行之后,我们就能通过HBase的shell看到一个新的空表:
- $ 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
- xyz
- 1 row(s) in 0.0530 seconds
- hbase(main):002:0> describe "xyz"
- DESCRIPTION ENABLED
- {NAME => 'xyz', FAMILIES => [{NAME => 'cf1', COMPRESSION => 'NONE', VE true
- RSIONS => '3', TTL => '2147483647', BLOCKSIZE => '65536', IN_MEMORY =>
- 'false', BLOCKCACHE => 'true'}]}
- 1 row(s) in 0.0220 seconds
- hbase(main):003:0> scan "xyz"
- ROW COLUMN+CELL
- 0 row(s) in 0.0060 seconds
注意,即使在映射中配置了“val”这个列名,但是在hbase shell输出的描述中,只能看到列族(column family)的名字“cf1”。这是因为在HBase中,只有列族(而不是列)的名字会被保存在表级的元数据中;列族中的列名只能保存在底层的列数据中。
这里将介绍如何将数据从Hive中转移到HBase的表中(如果创建一个示例表pokes,可以参考GettingStarted):
- INSERT OVERWRITE TABLE hbase_table_1 SELECT * FROM pokes WHERE foo=98;
使用HBase shell来验证一下数据是否被加载:
- hbase(main):009:0> scan "xyz"
- ROW COLUMN+CELL
- 98 column=cf1:val, timestamp=1267737987733, value=val_98
- 1 row(s) in 0.0110 seconds
通过hive进行检索的结果是:
- hive> select * from hbase_table_1;
- Total MapReduce jobs = 1
- Launching Job 1 out of 1
- ...
- OK
- 98 val_98
- Time taken: 4.582 seconds
Inserting large amounts of data may be slow due to WAL overhead; if you would like to disable this, make sure you have HIVE-1383 (as of Hive 0.6), and then issue this command before the INSERT:
插入大量的数据将会因为WAL机制导致速度缓慢;如果想禁用该功能,要确保已经打过HIVE-1383(针对hive 0.6),然后在插入数据之前,执行以下命令:
- set hive.hbase.wal.enabled=false;
警告: 禁用WAL功能将会导致HBase在异常出错时丢失数据,所以只能在还有其他恢复手段的时候使用这个功能。
如果你想让hive访问HBase上已经存在的表,可以使用创建外表功能“CREATE EXTERNAL TABLE”:
- 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" = "some_existing_table");
hbase.columns.mapping仍然是必需的,而且要保证它与HBase表上现有的列族相对应。hbase.table.name是可选项。
列的映射
这里有两种SERDEPROPERTIES,将会对HBase列映射到hive产生影响:
- hbase.columns.mapping
- hbase.table.default.storage.tepy: 它可以被设置为“string”(默认值)或者binary,这个选项只在hive0.9版本以后才可用,因为之前的版本只支持string。
当前可用的列映射配置方法多少有些繁琐:
- 对于每个hive列,表的创建者必须在hbase.columns.mapping字符串中,指定一系列相对应逗号分隔的映射项(有多少个hive列,就必须有多少个映射项与之相对于),注意空格不能用来表示entry,因为空格会被解释成列名的一部分。
- 一个映射项必须为如下的形式:key或者
列族名:[列名][#(二进制|字符串)(通过#的方式指定该映射项在HBase中以二进制数的形式保存,在hive 0.9.0版本之前,没有此功能)
- 如果没有特别指定,则使用hbase.table.default.storage.type
- Any prefixes of the valid values are valid too (i.e.
#binstead of#binary) - 如果你指定一个列为二进制,则在HBase相应的单元格中以HBase的bytes类来保存相应的数值
- 必须指定一个:key映射,当前还不支持复合主键
- (注意在0.6版本的HIVE-1228之前,:key还不被支持,第一个hive列会隐式的被作为主键(rowkey);在Hive 0.6版本以后,强烈的推荐用户明确的指定作为rowkey的列;未来有可能会不再支持隐式主键的方式)
- if no column-name is given, then the Hive column will map to all columns in the corresponding HBase column family, and the Hive MAP datatype must be used to allow access to these (possibly sparse) columns
- 当前还没有方法能够读取HBase中的时间戳属性,查询中只能读取最新时间戳对应的数据
- 因为HBase没有在列中给出数据类型的信息,所以序列化/反序列化模块先将其转换为字符串再存储到HBase中;现在还没有方法对每个列加入一个用户自定的序列化/反序列化模块。
- 并不需要引用HBase中的每个列族,但是这会导致Hive表无法访问到HBase中的这个列;可以将多个Hive表映射到一个HBase表中
下面几段将会通过一个具体的例子来介绍当前可以使用的几种映射方式:
多个列和列族
这里有个例子是三个hive列映射到两个HBase的列族,两个Hive列(value1、value2)对应一个列族(a,其中两个HBase列名为b、c),另一个Hive列则对应一个列族(d)中的单独的列(e)
- 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;
在hive中查看表结构,结果如下所示:
- hbase(main):014:0> describe "hbase_table_1"
- DESCRIPTION ENABLED
- {NAME => 'hbase_table_1', 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 hbase_table_1;
- 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类型映射整个列族
这里,举一个Hive使用MAP类型来读取这个column family的例子。每行包含不同的列,列的命名根据map中的key,列的值为map中的value:
- CREATE TABLE hbase_table_1(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_1 SELECT map(bar, foo), foo FROM pokes
- WHERE foo=98 OR foo=100;
这个例子同时也验证了hive使用的第一个列不一定是rowkey所在的列
这个表在HBase中看起来是这样的:
- hbase(main):012:0> scan "hbase_table_1"
- 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 hbase_table_1;
- 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列命名,所以如下的表定义方式将会出错:
- CREATE TABLE hbase_table_1(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方式可以把一个hive列映射到整个列族:
- CREATE TABLE hbase_table_1(key int, value string)
- 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 string)
使用二进制列的例子:
依赖默认的hbase.table.default.storage.type:
- CREATE TABLE hbase_table_1 (key int, value string, foobar double)
- STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
- WITH SERDEPROPERTIES (
- "hbase.columns.mapping" = ":key#b,cf:val,cf:foo#b"
- );
特别指定hbase.table.default.storage.type为二进制:
- CREATE TABLE hbase_table_1 (key int, value string, foobar double)
- STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
- WITH SERDEPROPERTIES (
- "hbase.columns.mapping" = ":key,cf:val#s,cf:foo",
- "hbase.table.default.storage.type" = "binary"
- );
hive与hbase集成的更多相关文章
- 新闻实时分析系统Hive与HBase集成进行数据分析
(一)Hive 概述 (二)Hive在Hadoop生态圈中的位置 (三)Hive 架构设计 (四)Hive 的优点及应用场景 (五)Hive 的下载和安装部署 1.Hive 下载 Apache版本的H ...
- 新闻网大数据实时分析可视化系统项目——12、Hive与HBase集成进行数据分析
(一)Hive 概述 (二)Hive在Hadoop生态圈中的位置 (三)Hive 架构设计 (四)Hive 的优点及应用场景 (五)Hive 的下载和安装部署 1.Hive 下载 Apache版本的H ...
- 新闻实时分析系统Hive与HBase集成进行数据分析 Cloudera HUE大数据可视化分析
1.Hue 概述及版本下载 1)概述 Hue是一个开源的Apache Hadoop UI系统,最早是由Cloudera Desktop演化而来,由Cloudera贡献给开源社区,它是基于Python ...
- Hive与HBase集成进行数据分析
我们把hive的安装包上传的节点3来 解压 现在我们还是老规矩通过notopad++来连接我们的虚拟机来配置文件,把下面这两个文件重命名一下 修改这个文件 对hive-env.sh我们修改这里 下面我 ...
- 集成Hive和HBase
1. MapReduce 用MapReduce将数据从本地文件系统导入到HBase的表中, 比如从HBase中读取一些原始数据后使用MapReduce做数据分析. 结合计算型框架进行计算统计查看HBa ...
- Hive On HBase实战
1.概述 HBase是一款非关系型.分布式的KV存储数据库.用来存储海量的数据,用于键值对操作.目前HBase是原生是不包含SQL操作,虽然说Apache Phoenix可以用来操作HBase表,但是 ...
- 全网最详细的hive-site.xml配置文件里如何添加达到Hive与HBase的集成,即Hive通过这些参数去连接HBase(图文详解)
不多说,直接上干货! 一般,普通的情况是 全网最详细的hive-site.xml配置文件里添加<name>hive.cli.print.header</name>和<na ...
- 3.12-3.16 Hbase集成hive、sqoop、hue
一.Hbase集成hive https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration 1.说明 Hive与HBase整合在一起 ...
- hive和hbase整合的原因和原理
为什么要进行hive和hbase的整合? hive是高延迟.结构化和面向分析的: hbase是低延迟.非结构化和面向编程的. Hive集成Hbase就是为了使用hbase的一些特性.或者说是中和它们的 ...
随机推荐
- jqgrid使用sql row_number进行分页
背景 系统中使用了jqgrid的展示,现在要处理10w+的数据量 现状 使用了全查询的,查询到了10w+的数据放到了datatable中,每次页面刷新需要9秒多,并且传递给另一个dll来处理一些事情. ...
- 现代程序设计——homework-01
1.我的GitHub用户 首先,接触到现代程序设计这门课之后我才正式开始使用GitHub和它的客户端,以前都是去网站看代码.扒样例.我注册的账户名为:hennande.目前该账户中有我的第一份关于ho ...
- Java经典面试题
1. Java中的异常处理机制的简单原理和应用. 当Java 程序违反了Java的语义规则时,Java虚拟机就会将发生的错误表示为一个异常.违反语义规则包括2种情况.一种是Java类库内置的语义检查. ...
- CSS区块、浮动、定位、溢出、滚动条
CSS中区块的使用 CSS中浮动的使用 CSS中定位的使用 CSS中溢出的使用 CSS中滚动条的使用 17.1 CSS中区块的使用 属性名称 属性值 ...
- javascript深入理解闭包(转)
一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之处,就在于函数内部可以直接读取全局变量 ...
- git 快速入门(二)
一.引子 git代码托管的优秀工具之一, 其工作原理和svn截然不同.一旦拥有主干master分支权限, 只要在本地拉取主干分支, 可以随时随地切换分支. 它拥有众多优点,eg :支持在断网的情况下, ...
- 搭建maven+spring+mybatis工程
一.maven 命令搭建web项目 可以参考我之前的一篇博文maven快速入门 1.搭建web工程 mvn archetype:generate -DgroupId=com.yuanmeng.spri ...
- XMPP——Smack[2]会话、消息监听、字体表情和聊天窗口控制
连接之后,拿到了connection,通过它可以搞定会话 建立一个会话 MessageListener msgListener = new MessageListener() { public voi ...
- iOS相机权限、相册权限、定位权限判断
1.判断用户是否有权限访问相册 #import <AssetsLibrary/AssetsLibrary.h> ALAuthorizationStatus author = [ALAsse ...
- HDU 5481 Desiderium 动态规划
Desiderium Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=548 ...
