原創乾貨 | Hive與HBase的集成實踐

註:若需轉載,請註明出處!

Hive與HBase集成實踐

大數據平台搭建 hive-2.0.0 hbase 1.1.3

    • Hive與HBase集成
      • 1. 具體步驟
        • 1. 拷貝jar包
        • 2. 在Hive的類路徑中添加一些這些jar包
      • 2. Hive集成HBase的原理
        • 1. Storage Handler
        • 2. 使用
        • 3. 欄位映射
      • 3. 示例
        • 1. 多列和列族
        • 2. Hive的Map欄位與HBase列族

環境說明

  • CentOS 6.7
  • Hadoop 2.7.2
  • Hive 2.0.0
  • HBase 1.1.3

1. 具體步驟

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>n <name>hive.aux.jars.path</name>n <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>n <description>The location of the plugin jars that contain implementations of user defined functions and serdes.</description>n </property>n

  • 在$HIVE_HOME/conf/下新建.hiverc文件,加入下列語句:

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

hive在執行命令前會先讀取.hiverc的文件中的內容

啟動Hive 和 HBase即可使用,具體示例如第3節。

2. 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;n

但是關閉WAL可能會使HBase發生錯誤時出現數據丟失,所以建議只有在你已有其他數據恢復策略時才使用這種設置。

若想使Hive可以訪問已存在的HBase表,可以使用下面的語句創建這樣的Hive表:

CREATE EXTERNAL TABLE hbase_table_2(key int, value string) nSTORED BY org.apache.hadoop.hive.hbase.HBaseStorageHandlernWITH SERDEPROPERTIES ("hbase.columns.mapping" = "cf1:val")nTBLPROPERTIES("hbase.table.name" = "xyz", "hbase.mapred.output.outputtable" = "xyz");n

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中的列名

3. 示例

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) nSTORED BY org.apache.hadoop.hive.hbase.HBaseStorageHandlernWITH SERDEPROPERTIES (n"hbase.columns.mapping" = ":key,a:b,a:c,d:e"n);nINSERT OVERWRITE TABLE hbase_table_1 SELECT foo, bar, foo+1, foo+2 nFROM pokes WHERE foo=98 OR foo=100;n

此表在HBase中是這個樣子的:

hbase(main):006:0> describe hive_hbase.hbase_table_2nTable hive_hbase.hbase_table_2 is ENABLED nhive_hbase.hbase_table_2 nCOLUMN FAMILIES DESCRIPTION n{NAME => a, BLOOMFILTER => ROW, VERSIONS => 1, IN_MEMORY => false, KnEEP_DELETED_CELLS => FALSE, DATA_BLOCK_ENCODING => NONE, TTL => FOREVERn, COMPRESSION => NONE, MIN_VERSIONS => 0, BLOCKCACHE => true, BLOCKSInZE => 65536, REPLICATION_SCOPE => 0} n{NAME => d, BLOOMFILTER => ROW, VERSIONS => 1, IN_MEMORY => false, KnEEP_DELETED_CELLS => FALSE, DATA_BLOCK_ENCODING => NONE, TTL => FOREVERn, COMPRESSION => NONE, MIN_VERSIONS => 0, BLOCKCACHE => true, BLOCKSInZE => 65536, REPLICATION_SCOPE => 0} n2 row(s) in 0.0190 secondsnnhbase(main):007:0> scanhive_hbase.hbase_table_2nROW COLUMN+CELL n 100 column=a:b, timestamp=1464598569847, value=val_100 n 100 column=a:c, timestamp=1464598569847, value=101 n 100 column=d:e, timestamp=1464598569847, value=102 n 98 column=a:b, timestamp=1464598569847, value=val_98 n 98 column=a:c, timestamp=1464598569847, value=99 n 98 column=d:e, timestamp=1464598569847, value=100 n2 row(s) in 0.0200 secondsn

再回到Hive中查詢此表:

hive> select * from hbase_table_2;nOKn100 val_100 101 102n98 val_98 99 100nTime taken: 0.298 seconds, Fetched: 2 row(s)n

2. Hive的Map欄位與HBase列族

如何使用Hive的Map數據類型訪問列族,每行可以有很多不同的列,而列名正好對應到Map類型欄位的Keys,而列值正好對應到Map類型欄位的Map值。Hive建表SQL如下:

CREATE TABLE hbase_table_3(value map<string,int>, row_key int) nSTORED BY org.apache.hadoop.hive.hbase.HBaseStorageHandlernWITH SERDEPROPERTIES (n"hbase.columns.mapping" = "cf:,:key"n);nINSERT OVERWRITE TABLE hbase_table_3 SELECT map(bar, foo), foo FROM pokes nWHERE foo=98 OR foo=100;n

這個表在HBase中是長這個樣子:

hbase(main):009:0> scanhive_hbase.hbase_table_3nROW COLUMN+CELL n 100 column=cf:val_100, timestamp=1464600230691, value=100 n 98 column=cf:val_98, timestamp=1464600230691, value=98 n2 row(s) in 0.0220 secondsn

再回到Hive中查詢此表:

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

----------------------------------

作者:Mars

大數據系列免費視頻教程 【Linux、Hadoop、Spark、Kylin、Hive、HBase、Sqoop、日誌分析等】 大數據系列免費視頻教程 【Linux、Hadoop、Spark、Kylin、Hive、HBase、Sqoop、日誌分析等】

最近很多人私信問我問題,平常知乎評論看到不多,如果沒有及時回復,大家也可以加小編微信:tszhihu,進知乎大數據分析挖掘交流群,可以跟各位老師互相交流。謝謝。


推薦閱讀:

Hive JDBC入門示例
大數據那些事(7):騰飛的拉丁豬
在Hive中適不適合像傳統數據倉庫一樣利用維度建模?
為何Hive中的數據不均勻分布會導致數據傾斜?
Hive On Spark, SparkSQL On Spark, 與Spark On YARN如何定義呢?

TAG:Hive | HBase | 大数据 |