原創乾貨 | 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列族
- 1. 具體步驟
- Hive與HBase集成
環境說明
- CentOS 6.7
- Hadoop 2.7.2
- Hive 2.0.0
- HBase 1.1.3
1. 具體步驟
1. 拷貝jar包
- 首先刪除$HIVE_HOME/lib下HBase和ZooKeeper相關的jar包
- 然後重新拷貝$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如何定義呢?