zoukankan      html  css  js  c++  java
  • Hive和HBase整合用户指南

    本文讲解的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设置合理的扫描缓存

  • 相关阅读:
    最近邻插值
    tp类型自动转换和自动完成
    tp读取器和写入器
    tp模型和数据库操作方法
    tp数据库操作
    tp请求和响应
    tp配置+路由+基本操作
    git的常见操作方法
    php 检查该数组有重复值
    公众号的TOKEN配置PHP代码
  • 原文地址:https://www.cnblogs.com/huanghanyu/p/13041926.html
Copyright © 2011-2022 走看看