Hive是一個基于Hadoop的開源數(shù)據(jù)倉庫工具,用于存儲和處理海量結(jié)構(gòu)化數(shù)據(jù)。它把海量數(shù)據(jù)存儲于Hadoop文件系統(tǒng),而不是數(shù)據(jù)庫,但提供了一套類數(shù)據(jù)庫的數(shù)據(jù)存儲和處理機(jī)制,并采用類SQL語言對這些數(shù)據(jù)進(jìn)行自動化管理和處理。我們可以把Hive中海量結(jié)構(gòu)化數(shù)據(jù)看成一個個的表,而實(shí)際上這些數(shù)據(jù)是分布式存儲在HDFS 中的。Hive經(jīng)過對語句進(jìn)行解析和轉(zhuǎn)換,最終生成一系列基于Hadoop 的MapReduce任務(wù),通過執(zhí)行這些任務(wù)完成數(shù)據(jù)處理。
使用Hive的命令行接口,感覺很像操作關(guān)系數(shù)據(jù)庫,但是Hive和關(guān)系數(shù)據(jù)庫還是有很大的不同,具體總結(jié)如下:
一是存儲文件的系統(tǒng)不同。Hive使用的是Hadoop的HDFS,關(guān)系數(shù)據(jù)庫則是服務(wù)器本地的文件系統(tǒng)。
二是計算模型不同。Hive使用MapReduce計算模型,而關(guān)系數(shù)據(jù)庫則是自己設(shè)計的計算模型。
三是設(shè)計目的不同。關(guān)系數(shù)據(jù)庫都是為實(shí)時查詢的業(yè)務(wù)設(shè)計的,而Hive則是為海量數(shù)據(jù)做數(shù)據(jù)挖掘設(shè)計的,實(shí)時性很差。實(shí)時性的區(qū)別導(dǎo)致Hive的應(yīng)用場景和關(guān)系數(shù)據(jù)庫有很大的不同。
四是擴(kuò)展能力不同。Hive通過集成Hadoop使得很容易擴(kuò)展自己的存儲能力和計算能力,而關(guān)系數(shù)據(jù)庫在這個方面要比數(shù)據(jù)庫差很多。
Hive的技術(shù)架構(gòu)如下圖所示。
由上圖可知,Hadoop和MapReduce是Hive架構(gòu)的根基。Hive架構(gòu)包括如下組件:CLI(command line interface)、JDBC/ODBC、Thrift Server、Web GUI、Metastore和Driver(Complier、Optimizer和Executor),這些組件可分為服務(wù)端組件和客戶端組件兩大類。
首先來看服務(wù)端組件:
Driver組件包括Complier、Optimizer和Executor,它的作用是將我們寫的HiveQL語句進(jìn)行解析、編譯優(yōu)化,生成執(zhí)行計劃,然后調(diào)用底層的MapReduce計算框架。
Metastore組件是元數(shù)據(jù)服務(wù)組件,它存儲Hive的元數(shù)據(jù),Hive的元數(shù)據(jù)存儲在關(guān)系數(shù)據(jù)庫里,支持的關(guān)系數(shù)據(jù)庫有derby和mysql。元數(shù)據(jù)對于Hive十分重要,因此Hive支持把Metastore服務(wù)獨(dú)立出來,安裝到遠(yuǎn)程的服務(wù)器集群里,從而解耦Hive服務(wù)和Metastore服務(wù),保證Hive運(yùn)行的健壯性。
Thrift Server是Facebook開發(fā)的一個軟件框架,它用來進(jìn)行可擴(kuò)展且跨語言的服務(wù)的開發(fā),Hive集成了該服務(wù),能讓不同的編程語言調(diào)用Hive的接口。
再來看看客戶端組件:
CLI即command lineinterface,命令行接口。
JDBC/ODBC 是Thrift的客戶端。
Web GUI是Hive客戶端提供的一種通過網(wǎng)頁的方式訪問Hive的服務(wù)。這個接口對應(yīng)Hive的hwi組件,使用前要啟動hwi服務(wù)。
Hive自帶了許多服務(wù),可在運(yùn)行時通過service選項(xiàng)來明確指定使用什么服務(wù),或通過--service help來查看幫助。下面介紹最常用的一些服務(wù)。
(1)CLI:這是Hive的命令行界面,用的比較多。這是默認(rèn)的服務(wù),直接可以在命令行里面使用。
(2)hiveserver:這個可以讓Hive以提供Trift服務(wù)的服務(wù)器形式來運(yùn)行,可以允許許多不同語言編寫的客戶端進(jìn)行通信??梢酝ㄟ^設(shè)置HIVE_PORT環(huán)境變量來設(shè)置服務(wù)器所監(jiān)聽的端口號,在默認(rèn)的情況下,端口為 10000。最新版本(hive1.2.1)用hiveserver2取代了原有的hiveserver。
(3)hwi:它是Hive的Web接口,是hive cli的一個web替換方案。
(4)jar:與Hadoop jar等價的Hive接口,這是運(yùn)行類路徑中同時包含Hadoop和Hive類的Java應(yīng)用程序的簡便方式。
(5)Metastore:用于連接元數(shù)據(jù)庫(如mysql)。在默認(rèn)情況下,Metastore和Hive服務(wù)運(yùn)行在同一個進(jìn)程中,端口號為9083。使用這個服務(wù),可以讓Metastore作為一個單獨(dú)的進(jìn)程運(yùn)行,我們可以通過METASTORE_PORT來指定監(jiān)聽的端口號。
內(nèi)嵌模式使用內(nèi)嵌的Derby數(shù)據(jù)庫存儲元數(shù)據(jù),只能單用戶操作,一般用于單元測試。其架構(gòu)圖如下所示。
本地模式與內(nèi)嵌模式最大的區(qū)別在于數(shù)據(jù)庫由內(nèi)嵌于hive服務(wù)變成獨(dú)立部署(一般為mysql數(shù)據(jù)庫),hive服務(wù)使用jdbc訪問元數(shù)據(jù),多個服務(wù)可以同時訪問。mysql數(shù)據(jù)庫用于存儲元數(shù)據(jù),可安裝在本地或遠(yuǎn)程服務(wù)器上,在配置文件hive-site.xml中指定jdbc URL、驅(qū)動、用戶名、密碼等屬性。其中屬性hive.metastore.uris的值為空,表示為嵌入模式或本地模式。在本地模式中,每種hive服務(wù)(如cli、hiveserver2、hwi)都內(nèi)置啟動了一個metastore服務(wù),用于連接mysql元數(shù)據(jù)庫。其架構(gòu)圖如下所示。
遠(yuǎn)程模式將原內(nèi)嵌于hive服務(wù)中的metastore服務(wù)獨(dú)立出來單獨(dú)運(yùn)行,hive服務(wù)通過thrift訪問metastore,這種模式可以控制到數(shù)據(jù)庫的連接等。其中,metastore服務(wù)器需要通過hive-site.xml配置jdbc URL、驅(qū)動、用戶名、密碼等屬性,hiveserver2服務(wù)器和cli客戶端需要通過hive-site.xml配置hive.metastore.uris屬性,用于指定metastore服務(wù)地址(如thrift://localhost:9083),metastore服務(wù)器通過./hive --service metastore開啟metastore服務(wù),hiveserver2服務(wù)器通過./hive --service hiveserver2開啟hiveserver服務(wù),客戶端通過./hive shell 或./beeline進(jìn)行連接。其架構(gòu)圖如下所示。
遠(yuǎn)程模式下可以按如下部署規(guī)劃:
(1)元數(shù)據(jù)服務(wù)器:部署metastore服務(wù)和mysql數(shù)據(jù)庫。
(2)hiveserver服務(wù)器:用于部署hiveserver2服務(wù),可通過thrift訪問metastore。
(3)客戶服務(wù)器:部署hive客戶端,可以基于cli、beeline或直接使用thrift訪問hiveserver2。
操作系統(tǒng)為ubuntu14.04,需要安裝并啟動Hadoop及HBase。
// 切換root用戶
$ su root
// 檢查mysql是否安裝
# netstat -tap | grep mysql
// 在線安裝mysql
# apt-get install mysql-server mysql-client
// 啟動mysql
# start mysql
// 設(shè)置開機(jī)自啟動
# /etc/init.d/mysql start
// 設(shè)置root用戶密碼
# mysqladmin -u root password 'root'
// 使用客戶端登錄mysql
$ mysql -u root -p
// 創(chuàng)建hive用戶,密碼為hive
> create user 'hive' identified by 'hive';
// 創(chuàng)建數(shù)據(jù)庫hivemeta,用于存放hive元數(shù)據(jù)
> create database hivemeta;
// 將hivemeta數(shù)據(jù)庫的所有權(quán)限賦予hive用戶,并允許遠(yuǎn)程訪問
> grant all privileges on hivemeta.* to 'hive'@'%' identified by 'hive';
> flush privileges;
// 可查看用戶hive的權(quán)限情況
> use mysql;
> select host, user, password from user;
// 解壓安裝包
$ tar -xvf hive-1.1.0-cdh5.7.1.tar.gz
// 進(jìn)入hive的配置目錄
$ cd hive-1.1.0-cdh5.7.1/conf/
// 修改hive-env.sh文件
$ cp hive-env.sh.template hive-env.sh
$ vim hive-env.sh
HADOOP_HOME=/home/developer/app/hadoop-2.6.0-cdh5.7.1
// 創(chuàng)建hive-site.xml文件并配置
$ vimhive-site.xml
// 修改hive-log4j.properties指定日志輸出路徑
$ cp hive-log4j.properties.template hive-log4j.properties
$ vim hive-log4j.properties
hive.root.logger=info,DRFA
hive.log.dir=/home/developer/app/hive-1.1.0-cdh5.7.1/logs
// 在http://www.mysql.com/products/connector/下載JDBC Driver for MySQL并復(fù)制到hive的lib目錄中
$ cp mysql-connector-java-5.1.39-bin.jar/home/developer/app/hive-1.1.0-cdh5.7.1/lib/
$ cd ~
$ vim.bashrc
export HIVE_HOME=/home/developer/app/hive-1.1.0-cdh5.7.1
export PATH=$PATH:$HIVE_HOME/bin
$ source.bashrc
// 啟動hive的cli服務(wù)
$ hive
// 測試
> show databases;
// 后臺啟動hiveserver2
$nohup hive --service hiveserver2 &
注:beeline依賴hiveserver2提供的thirft服務(wù),必須啟動,其默認(rèn)端口為10000
// 使用beeline
$beeline
// 連接hive
> !connectjdbc:hive2://localhost:10000
注:需要通過hadoop用戶登錄,否則沒有hdfs操作權(quán)限
// 測試
> show databases;
// 啟動hive的cli服務(wù)
$ hive
// 創(chuàng)建表
> create table user(id string,name string,age string) row format delimited fields terminated by '\t';
// 查看測試數(shù)據(jù)
$ cat data.txt
// 將本地數(shù)據(jù)導(dǎo)入hive
> load data local inpath '/home/developer/data.txt' overwrite into table user;
// 查看導(dǎo)入的數(shù)據(jù)
> select * from user;
// 查看數(shù)據(jù)條數(shù)
> select count(*) from user;
Hive與HBase整合的實(shí)現(xiàn)是利用兩者本身對外的API接口互相通信來完成的,其具體工作交由Hive的lib目錄中的hive-hbase-handler-*.jar工具類來實(shí)現(xiàn),通信原理如下圖所示。
Hive整合HBase后的使用場景:
(一)通過Hive把數(shù)據(jù)加載到HBase中,數(shù)據(jù)源可以是文件也可以是Hive中的表。
(二)通過整合,讓HBase支持JOIN、GROUP等SQL查詢語法。
(三)通過整合,不僅可完成HBase的數(shù)據(jù)實(shí)時查詢,也可以使用Hive查詢HBase中的數(shù)據(jù)完成復(fù)雜的數(shù)據(jù)分析。
// 如果hbase是集群,需要修改hive-site.xml文件配置
$ vim hive-site.xml
// 將hbase lib目錄下的所有文件復(fù)制到hive lib目錄中
$ cd app/hive-1.1.0-cdh5.7.1/
$ cp ~/app/hbase-1.2.0-cdh5.7.1/lib/* lib/
// 在hive中創(chuàng)建映射表
$ hive shell
> create table hive_hbase_test(key int,value string) stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties("hbase.columns.mapping"=":key,cf1:val") tblproperties("hbase.table.name"="hive_hbase_test");
備注:在hive中創(chuàng)建表hive_hbase_test,這個表包括兩個字段(int型的key和string型的value),映射為hbase中的表hive_hbase_test,key對應(yīng)hbase的rowkey,value對應(yīng)hbase的cf1:val列。
// 在hbase中查看是否存在映射表
$ hbase shell
> list
// 創(chuàng)建測試數(shù)據(jù)
$ vim poke.txt
1 zhangsan
2 lisi
3 wangwu
// 在hive中創(chuàng)建一個poke表并加載測試數(shù)據(jù)
> create table poke(key int,valuestring) row format delimited fields terminated by '\t';
> load data local inpath'/home/developer/poke.txt' overwrite into table poke;
> select * from poke;
// 將hive的poke表中的數(shù)據(jù)加載到hive_hbase_test表
> insert overwrite table hive_hbase_test select * from poke;
> select * from hive_hbase_test;
// 查看hbase的hive_hbase_test表中是否有同樣的數(shù)據(jù)
> scan 'hive_hbase_test'
需要說明以下幾點(diǎn):
(一)Hive映射表的字段是HBase表字段的子集。整合之后的Hive表不能被修改。
(二)Hive中的映射表不能直接插入數(shù)據(jù),所以需要通過將數(shù)據(jù)加載到另一張poke表,然后通過查詢poke表將數(shù)據(jù)加載到映射表。
(三)上述示例是通過創(chuàng)建內(nèi)部表的方式將Hive表映射到HBase表,HBase表會自動創(chuàng)建,而且Hive表被刪除后HBase表也會自動刪除。
(四)如果HBase表已有數(shù)據(jù),可以通過創(chuàng)建Hive外部表的方式將Hive表映射到HBase表,通過HQLHive表實(shí)現(xiàn)對HBase表的數(shù)據(jù)分析。Hive表刪除將不會對HBase表造成影響。創(chuàng)建外部表的方法如下:
> create external table hive_hbase_test(key int,value string)stored by 'org.apache.hadoop.hive.hbase.HBaseStorageHandler' with serdeproperties("hbase.columns.mapping"=":key,cf1:val") tblproperties("hbase.table.name"="hive_hbase_test");