當(dāng)我們用HBase 存儲實時數(shù)據(jù)的時候, 如果要做一些數(shù)據(jù)分析方面的操作, 就比較困難了, 要寫MapReduce Job。 Hive 主要是用來做數(shù)據(jù)分析的數(shù)據(jù)倉庫,支持標(biāo)準(zhǔn)SQL 查詢, 做數(shù)據(jù)分析很是方便,于是便很自然地想到用Hive來載入HBase的數(shù)據(jù)做分析, 但是很奇怪地是, 上網(wǎng)查了一下, 只看到以下兩種情況:
1. 如何用Hive 往HBase里面插入大量的數(shù)據(jù)。
2. Hive 與HBase集成, 直接從Hive里面連HBase的數(shù)據(jù)庫進(jìn)行查詢。參考鏈接: https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration
選項1是我們需求的逆操作, 直接忽略, 選項2, 雖然沒有做專門的Benchmark, 但總感覺直接對HBase進(jìn)行查詢操作不怎么靠譜, 如果我們要頻繁做很多類型的數(shù)據(jù)分析, 那HBase的壓力一定會倍增。
難道沒有把HBase里面的數(shù)據(jù)直接導(dǎo)入到Hive當(dāng)中的工具或者方法嗎?
找了一會, 似乎沒找到, 那么只好自己想一個解決方案了。
思路:
利用選項2, 先打通Hive對HBase指定表的全表訪問, 再建立一個新的空表, 把查詢出來的數(shù)據(jù)全部導(dǎo)入到新表當(dāng)中, 以后的所有數(shù)據(jù)分析操作在新表中完成。
說干就干, 讓我們試一個簡單的例子。
首先在HBase里面建一個表, 名為 student, 包含 id 和 name 兩個column.
hbase shell create 'student', 'id', 'name'
向表中插入兩行數(shù)據(jù)
put 'student', 'row1', 'id:val', '1' put 'student', 'row1', 'name:val', 'Tony' put 'student', 'row2', 'id:val', '2' put 'student', 'row2', 'name:val', 'Mike'
注意:在插入數(shù)據(jù)的時候一定要指定column (如id:val, name:value) 直接使用column family (如 id, name) 去存數(shù)據(jù)會導(dǎo)致后面Hive 建表的時候有問題。
掃描此表, 確定數(shù)據(jù)已經(jīng)插入
scan 'student' ROW COLUMN+CELL row1 column=id:val, timestamp=1384939342989, value=1 row1 column=name:val, timestamp=1384939365511, value=Tony row2 column=id:val, timestamp=1384939351444, value=2 row2 column=name:val, timestamp=1384939379245, value=Mike
建立Hive 對HBase的訪問
參考: https://cwiki.apache.org/confluence/display/Hive/HBaseIntegration
這里我們使用的是Pivotal 公司的Pivotal Hadoop,
hive --auxpath /usr/lib/gphd/hive/lib/hive-hbase-handler-0.11.0-gphd-2.1.1.0.jar,/usr/lib/gphd/hbase/hbase.jar,/usr/lib/gphd/zookeeper/zookeeper.jar,/usr/lib/gphd/hbase/lib/guava-11.0.2.jar -hiveconf hbase.zookeeper.quorum=centos62-3,centos62-4,centos62-5
解釋一下參數(shù):
后面三個jar 包主要是Hive 訪問時需要用到的, hhbase.zookeeper.quorum=centos62-3,centos62-4,centos62-5 是指hbase使用的是這三個zookeeper, 這樣就不用指定hbase master了。
這個命令運行完以后會打開Hive 的輸入終端。
從Hive建立可以訪問HBase的外部表
CREATE EXTERNAL TABLE student(key string, id int, name string) STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' WITH SERDEPROPERTIES ("hbase.columns.mapping" = "id:val,name:val") TBLPROPERTIES("hbase.table.name" = "student");
掃描student表, 確認(rèn)訪問成功:
hive> select * from student; OK row1 1 Tony row2 2 Mike
但是此時這個表實際上是一個虛擬表, 實際的數(shù)據(jù)還在HBase中。 下面需要在Hive中另建一個結(jié)構(gòu)一樣的空表, 再把數(shù)據(jù)導(dǎo)出來。
Hive中建立一個新的空表
CREATE TABLE new_student ( key string, id INT, name STRING) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' STORED AS TEXTFILE;
將數(shù)據(jù)從HBase中導(dǎo)入到新的Hive表中
hive> INSERT OVERWRITE TABLE new_student SELECT * FROM student;
確認(rèn)新表中數(shù)據(jù)正確:
hive> select * from new_student; OK row1 1 Tony row2 2 Mike
至此大功告成!
以后所有復(fù)雜的數(shù)據(jù)查詢和數(shù)據(jù)分析都可以在new_student表中完成。