天天看點

如何整合hive和hbase

值得信賴的合信雲 【文章來源:華為社群】

引言 為什麼要內建Hive和HBase

Hive和Hbase在大資料架構中處在不同位置,Hive是一個建構在Hadoop基礎之上的資料倉庫,主要解決分布式存儲的大資料處理和計算問題,Hive提供了類SQL語句,叫HiveQL,

通過它可以使用SQL查詢存放在HDFS上的資料,sql語句最終被轉化為Map/Reduce任務運作,但是Hive不能夠進行互動查詢——它隻能夠在Haoop上批量的執行Map/Reduce任務。

Hive适合用來對一段時間内的資料進行分析查詢,例如,用來計算趨勢或者網站的日志。Hive不應該用來進行實時的查詢。因為它需要很長時間才可以傳回結果。

Hbase是Hadoop database 的簡稱,是一種NoSQL資料庫,非常适用于海量明細資料(十億、百億)的随機實時查詢,如交易清單、軌迹行為等。

在大資料架構中,Hive和HBase是協作關系,Hive友善地提供了Hive QL的接口來簡化MapReduce的使用, 而HBase提供了低延遲的資料庫通路。如果兩者結合,可以利用MapReduce的優勢針對HBase存儲的大量内容進行離線的計算和分析。

Hive和HBase的通信原理

Hive與HBase整合的實作是利用兩者本身對外的API接口互相通信來完成的,

這種互相通信是通過$HIVE_HOME/lib/hive-hbase-handler-*.jar工具類實作的。通過HBaseStorageHandler,Hive可以擷取到Hive表所對應的HBase表名,列簇和列,InputFormat、OutputFormat類,建立和删除HBase表等。基本通信原理如下:

clipboard.png

spacer.gif

通路

Hive通路HBase中HTable的資料,實質上是通過MR讀取HBase的資料,而MR是使用HiveHBaseTableInputFormat完成對表的切分,擷取RecordReader對象來讀取資料的。

對HBase表的切分原則是一個Region切分成一個Split,即表中有多少個Regions,MR中就有多少個Map;

讀取HBase表資料都是通過建構Scanner,對表進行全表掃描,如果有過濾條件,則轉化為Filter。當過濾條件為rowkey時,則轉化為對rowkey的過濾;Scanner通過RPC調用RegionServer的next()來擷取資料。

簡單來說,Hive和Hbase的內建就是,打通了Hive和Hbase,使得Hive中的表建立之後,可以同時是一個Hbase的表,并且在Hive端和Hbase端都可以做任何的操作。

使用場景:

(一)将ETL操作的資料通過Hive加載到HBase中,資料源可以是檔案也可以是Hive中的表。

cj1.png

(二)Hbae作為Hive的資料源,通過整合,讓HBase支援JOIN、GROUP等SQL查詢文法。

cj2.png

(三)建構低延時的資料倉庫

cj3.png

一、 配置HBase環境

修改$HBASE_HOME/conf目錄下的hbase-env.sh,添加以下配置

export JAVA_HOME=/opt/java/jdk1.8

export HADOOP_HOME=/opt/hadoop/hadoop2.8

export HBASE_HOME=/opt/hbase/hbase1.2

export HBASE_CLASSPATH=/opt/hadoop/hadoop2.8/etc/hadoop

export HBASE_PID_DIR=/root/hbase/pids

export HBASE_MANAGES_ZK=false

說明:實際配置的路徑以自己的為準。HBASE_MANAGES_ZK=false 是不啟用HBase自帶的Zookeeper叢集。

修改 hbase-site.xml

編輯hbase-site.xml 檔案,在添加如下配置

<!-- 存儲目錄 -->

<property>

<name>hbase.rootdir</name>

<value>hdfs://test1:9000/hbase</value>

<description>The directory shared byregion servers.</description>

</property>

<!-- hbase的端口 --><property>

<name>hbase.zookeeper.property.clientPort</name>

<value>2181</value>

<description>Property from ZooKeeper'sconfig zoo.cfg. The port at which the clients will connect. </description>

</property>

<!-- 逾時時間 --><property>

<name>zookeeper.session.timeout</name>

<value>120000</value>

<!-- zookeeper 叢集配置。如果是叢集,則添加其它的主機位址 --><property>

<name>hbase.zookeeper.quorum</name>

<value>test1</value>

<name>hbase.tmp.dir</name>

<value>/root/hbase/tmp</value>

<!-- false是單機模式,true是分布式模式 -->

<name>hbase.cluster.distributed</name>

<value>false</value>

說明:hbase.rootdir:這個目錄是region server的共享目錄,用來持久化Hbase 。hbase.cluster.distributed :Hbase的運作模式。false是單機模式,true是分布式模式。若為false,Hbase和Zookeeper會運作在同一個JVM裡面。

二、Hive內建HBase的配置以及測試

1,配置通信接口

因為Hive與HBase內建是利用兩者本身對外的API接口互相通信來完成的,其具體工作交由Hive的lib目錄中的hive-hbase-handler-.jar工具類來實作。是以隻需要将hive的 hive-hbase-handler-.jar 複制到hbase/lib中就可以了。

切換到hive/lib目錄下

輸入:

cp hive-hbase-handler-*.jar /opt/hbase/hbase1.2/lib

注: 如果在hive整合hbase中,出現版本之類的問題,那麼以hbase的版本為主,将hbase中的jar包覆寫hive的jar包。

2,hive和hbase內建測試

在進行測試的時候,確定hadoop、hbase、hive環境已經成功搭建好,并且都成功啟動了。

打開xshell的兩個指令視窗

一個進入hive,一個進入hbase

2.1在hive中建立映射到hbase的表

通過複制上面的jar包,我們已經實作了hive和hbase底層的打通,在上層我們需要做的是使用HQL在hive中建立一個表

與hbase進行映射,為了友善,設定兩邊的表名都為t_employee,存儲的表也是這個表名。

在hive中輸入:

create table t_employee(id int,name string) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties("hbase.columns.mapping"=":key,st1:name") tblproperties("hbase.table.name"="t_employee","hbase.mapred.output.outputtable" = "t_employee");

說明:

a、這裡面出現了三個t_employee表名,第一個t_employee 是hive表中的名稱,(id int,name string) 是hive表結構。

在tblproperties 語句中還出現了2個t_employee表,

"hbase.table.name"定義的是在hbase中的表名 ,這個屬性是可選的,僅當你想在Hive和Hbase中使用不同名字的表名時才需要填寫,如果使用相同的名字則可以省略;

"hbase.mapred.output.outputtable"定義的第三個t_employee是存儲資料表的名稱,指定插入資料時寫入的表,如果以後需要往該表插入資料就需要指定該值,這個可以不要,表資料就存儲在第二個表中了 。

b、stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' :是指定處理的存儲器,就是hive-hbase-handler-*.jar包,要做hive和hbase的內建必須要加上這一句;

c、“hbase.columns.mapping” 是定義在hive表中的字段怎麼與hbase的列族進行映射。

例如:st1就是列族,name就是列。它們之間通過“:”連接配接。

在hive中建立的t_employee表,包括兩個字段(int型的id和string型的name),映射為hbase中的表t_employee,其中:key對應hbase的rowkey,value對應hbase的st1:name列。

表成功建立之後

在hive、hbase分别中檢視表和表結構

hive中輸入

show tables;

describe t_employee;

1.jpg

hbase輸入:

list

describe ‘t_employee’

2.jpg

可以看到表t_employee在hbase中已經建立成功了

2.2資料同步測試

進入hbase之後,在t_employee中添加兩條資料 然後查詢該表

put 't_employee','1001','st1:name','zhaoqian'

put 't_employee','1002','st1:name','sunli'

scan 't_employee'

3.jpg

然後切換到hive中查詢該表

select * from t_employee;

4.jpg

然後在hive中删除該表

注:這裡是要讓大家看到資料同步的結果,是以将表删除了。如果大家要做測試的話,是沒有必要删除該表的,因為在後面還會使用該表。

在hive中将表t_employee删除

drop table t_employee;

5.jpg

在Hbase中檢視:

6.jpg

可以看到在hbase中t_employee表也被删除了,hive和hbase之間的資料同步成功!

2.3 多列和列族的映射

我們來看一個更複雜一些的例子,Hive表中的3個字段與Hbase中的2個列族的映射。

Hive建表sql指令如下:

create table t_employee2(id int,name string,age,int,salary int)

stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

with serdeproperties("hbase.columns.mapping"=":id,a:b,a:c,d:e") ;

hive 表中的key字段預設與hbase中的row key 對應 ,

Hive字段(name和age)對應到1個Hbase列族(列族a的列b和c,即a:b和a:c),

另一個Hive字段(salary)對應到另一個Hbase列族的單個列(d:e),這裡我們并沒有指定hbase中的表名。

假設我們在hive 已有一salary表,現将表salary資料插入到表t_employee2:

insert overwrite table t_employee2 select * from salary;

m1.jpg

m2.jpg

2.4關聯查詢測試

從hive映射HBase

外部表測試——建立一個指向已經存在的Hbae表的Hive表

先在hbase中建一張t_employee_info表,添加兩個列族 st1,st2

然後檢視表結構

create 't_employee_info','st1','st2'

describe 't_employee_info'

17.jpg

對于在hbase已經存在的表,在hive中使用CREATE EXTERNAL TABLE來建立聯系

注意:建立外部表要使用EXTERNAL 關鍵字

create external table t_employee_info(id int,age int,sex string)

stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'

with serdeproperties("hbase.columns.mapping"=":key,st1:age,st2:sex")

tblproperties("hbase.table.name"="t_employee_info");

8.jpg

然後在t_employee_info 中添加資料

put 't_employee_info','1001','st2:sex','man'

put 't_employee_info','1001','st1:age','32'

put 't_employee_info','1002','st1:age','25'

put 't_employee_info','1002','st2:sex','woman'

9.jpg

然後在hive中查詢該表

select * from t_employee_info;

10.jpg

查詢到資料之後,然後将t_employee 和t_employee_info進行關聯查詢。

select * from t_employee a join t_employee_info b where a.id=b.id ;

11.png

說明:通過關聯查詢,可以得出表之間是可以關聯查詢的。

使用Hive內建HBase表的需注意

繼續閱讀