1 準備工作

1.1 軟件準備

Hive需要Hadoop的支持,在安裝Hive之前需要正確安裝Hadoop。目前Hive的最新版本為0.13.1,這個版本可在Hadoop 0.20.x, 0.23.x.y, 1.x.y, 2.x.y下使用。本文采用Hadoop 1.x中最新版本1.2.1。Hadoop使用環境中必須由JDK,本文下載JDK 7較新版本。同時,Hive將採用MySQL作為元數據庫。

1.2 集羣準備

Hadoop集羣中,數據存儲在分佈式文件系統中(一般為HDFS),並將MapReduce計算移到集羣中各台機器上。

HDFS集羣有兩類節點,並以管理者-工作者模式運行,即一個namenode(管理者),多個datanode(工作者)。namenode管理文件系統的命名空間,維護文件系統及整棵樹內所有的文件和目錄,同時記錄每個文件中各個塊所在的數據節點信息,但並不永久保存塊的位置信息,這些信息會在系統啓動時由數據節點重建。datanode是文件系統的工作節點,可根據需要存儲並檢索數據塊(受客户端或namenode調度),並定期向namenode發送它們所存儲的塊的列表。

MapReduce作業(job)有兩類節點控制其執行流程:一個jobtracker 和一系列tasktracker。其中, jobtracker通過調度tasktracker上運行的任務來協調所有運行在系統上的作業。tasktracker在運行任務的同時將運行進度報告發給jobtracker,jobtracker由此記錄每項作業任務的整體進度。

對於小集羣,在一個master機器上運行namenode和jobtracker通常沒問題。但如果HDFS集羣和文件數比較龐大,namenode需要使用更多內存,則namenode和jobtracker最好放在不同機器中。

此次搭建的小集羣僅供小實驗使用。只採用兩個節點:一個master(namenode & jobtracker),一個作為slave(datanode & tasktracker),其主機名命名與作用吻合,命為master和slave。 如有更多節點,則可將主機名命為master、slave1、slave2、slave3……

節點命名

IP

操作系統

master

192.168.1.115

Linux CentOS 64位

slave

192.168.1.116

Linux CentOS 64位

1、修改主機名

查看主機名:

1

hostname  $name

其中$name的值為該機的主機名稱。

1

vim  /etc /sysconfig /network

修改文件裏HOSTNAME的值並保存

備註:如是虛擬機可固定IP地址以防外部網絡環境變化造成麻煩。另外請關閉操作系統的防火牆。

添加上每台主機名字和地址的映射

1
2
3

vi etc /hosts
192.168.1.115 master
192.168.1.116 slave

2、驗證連接

1

reboot  -h

重啓電腦

檢查ping連接

在master中

1

ping slave

1.3 安裝JDK

1、查看操作系統中是否已安裝下載JDK

1

java  -version

2、安裝JDK

在命令行中輸入以下命令,或者雙擊rpm包

1

rpm  -ivh

3、修改系統配置環境變量~/.bash_profile文件

1

vim ~ /.bash_profile

在文件的最後面加入以下行:

1
2
3
4
5

#set java environment
JAVA_HOME= /usr /java /jdk1.7.0_65
PATH$JAVA_HOME /bin: $PATH
CLASSPATH$CLASSPATH:.: $JAVA_HOME /lib
export JAVA_HOME CLASSPATH PATH

重新加載.bash_profile文件使生效

1

source ~ /.bash_profile

備註:一般而言,配置環境變量時,如果所有用户都會使用,則可在/etc/profile裏配置;如果個人使用,就在自己的用户目錄下的.bash_profile裏配置。採用後者方法更為安全,它可以把使用這些環境變量的權限控制到用户級別。JAVA_HOME 設置為JAVA的安裝路徑。

4、檢驗java是否安裝成功

1

java  -version

如果輸出java version “1.7.0_65″等一系列信息,則表示安裝成功。

1.4 Hadoop用户準備

Hadoop最好不要使用root安裝(不推薦各個機器之間使用root訪問)。且最好在所有的Hadoop節點上建立相同的目錄(即建立相同的用户)。在所有節點中新增用户名hadoop。

在節點中使用root賬户登錄系統:

1

su root

1、添加用户

1

useradd hadoop

2、密碼修改

1

passwd hadoop

3、授權給hadoop用户

1

chown  -R hadoop:hadoop  /hadoop

提示輸入新密碼和重複輸入新密碼,退出root用户,用hadoop用户登錄

1.5 SSH無密碼登錄配置

在Hadoop中,namenode是通過SSH(Secure Shell)來啓動和停止各個DataNode上的各種守護進程的,這就須要在節點之間執行指令的時候是不須要輸入密碼的形式,故我們須要配置SSH運用無密碼公鑰認證的形式。

其配置方法是通過為hadoop上的用户hadoop生成其密鑰對,詢問其保存路徑時直接回車採用默認路徑,當提示要為生成的密鑰輸入pass phrase的時候,直接回車,也就是將其設定為空密碼。生成的密鑰對id_rsa,id_rsa.pub,默認存儲在/home/hadoop/.ssh目錄下,然後將id_rsa.pub的內容複製到每個機器(也包括本機)的/home/hadoop/.ssh/authorized_keys文件中。

首先退出root用户

1、生成公鑰

在master機器上,執行

1

ssh-keygen  -t

然後三個回車下去,此時會在~/.ssh目錄下生成一對密鑰

2、複製公鑰

首先把master上的公鑰追加到authorized_keys文件

1

cat id_dsa.pub  > > authorized_keys

查看authorized_keys文件的權限,如果不是600,修改為600.

1

chmod  600 authorized_keys

然後把master的公鑰文件拷貝到slaves上

1

scp id_dsa.pub slave:~ /.ssh /master.pub

3、修改權限

登錄到slave上

1
2

cd ~ /.ssh
cat master.pub  > >authorized_keys

查看authorized_keys文件的權限,如果不是600,修改為600.

4、測試

回到master服務器上

1

ssh slave

測試在master上是否不用輸入密碼便可以登錄到該slave上

1.6 常用命令

因集羣搭建主要在Linux下進行,可能會使用到的命令如下:

常用命令

例子

解釋

解壓縮命令

$tar zxvf filename.tar.gz

將FileName.tar.gz解壓

遠程複製命令

$scp –r file_source file_target

將file_source文件夾複製到file_target

權限設置命令

$chmod 777 file

將file的權限改為777

合併文件命令

$cat file1 file2 > file

將file1與file2合併為file

……

……

……

2 配置Hadoop

2.1 解壓Hadoop

集羣中所有的機器上都要安裝hadoop,可先在master上安裝,然後複製到其他節點中。

登錄master

將hadoop安裝包拷貝到home/hadoop/下並解壓

1

tar  -xzvf  /home /hadoop /hadoop-1.2.1.tar.gz

2.2 配置Hadoop

控制Hadoop安裝的配置文件較多,最重要的幾個文件如下表(這幾個文件都在hadoop/conf中)

1

cd ~ /hadoop-1.2.1 /conf

文件名稱

描述

hadoop-env.sh

記錄腳本要用的環境變量以運行Hadoop

core-site.xml

Hadoop Core的配置項,例如HDFS和MapReduce常用的I/O設置等

hdfs-site.xml

Hadoop守護進程的配置項,包括namenode、輔助namenode和datanode

mapred-site.xml

MapReduce守護進程的配置項,包括jobtracker和tasktracker

masters

運行輔助namenode的機器列表

slaves

運行datanode和tasktracker的機器列表

hadoop-metrics.properties

控制metrics在Hadoop上如何發佈的屬性

log4j.properties

系統日誌文件、namenode審計日誌、tasktracker子進程的任務日誌的屬性。

1. hadoop-env.sh

修改其中的的行:

1

export  JAVA_HOME= /usr /java /jdk1.7.0_65

JAVA_HOME修改為本地的JAVA_HOME路徑。

2. core-site.xml

這裏配置的是HDFS master(即namenode)的地址和端口號。

<configuration>

<property>

<name>fs.default.name</name>//指定HDFS的namenode和默認文件系統

<value>hdfs://master:9000</value>

<description>change your own hostname</description>

</property>

<property>

<name>hadoop.tmp.dir</name>//如沒有配置hadoop.tmp.dir參數,此時系統默認的臨時目錄為:/tmp/hadoo-hadoop。而這個目錄在每次重啓後都會被刪掉,必須重新執行format才行,否則會出錯。

<value>/home/hadoop/hadoop-1.2.1/tmp</value>

</property>

</configuration>

3. hdfs-site.xml

修改Hadoop中HDFS的配置,配置的備份方式默認為3

<configuration>

<property>

<name>dfs.replication</name> //數據副本數量

<value>1</value>

</property>

</configuration>

4. mapred-site.xml

修改Hadoop中MapReduce的配置文件,配置的是jobtracker的地址和端口。

<configuration>

<property>

<name>mapred.job.tracker</name>

<value>master:9001</value>

<description>change your own hostname</description>

</property>

</configuration>

5. masters

修改配置文件masters,命令

1

vim masters

刪除原有行,添加一行master(代表master服務器),保存退出。

6. slaves

修改配置文件slaves,命令

1

vim slaves

刪除原有的所有行,然後把所有的slave服務器的名稱添加到文件裏,一個slave服務器名佔一行,保存退出。

7. log4j.properties

HDFS的日誌能夠記錄所有的文件系統訪問請求。在默認配置下在,在log4j.properties屬性文件中的日誌闕值被設為ARN,可將WARN替換成INFO來啓動日誌審計特性,使每個HDFS事件均在namenode的日誌文件中生成記錄。

1

log4j.logger.org.apache.hadoop.hdfs.server.namenode.FSNamesystem.audit=WARN

2.3 分發Hadoop

通過scp命令把hadoop目錄拷貝到其他所有slave上去,命令

1

scp  -r  /home /hadoop /hadoop-1.2.1 / slave: /home /hadoop /

設置Hadoop環境變量,在所有機器上編輯~/.bash_profile文件

1

vi ~ /.bash_profile

末尾添加如下行:

1
2
3
4

#set Hadoop environment
export  HADOOP_HOME= /home /hadoop /hadoop-1.2.1
export  PATH$PATH$HADOOP_HOME /bin
export  CLASSPATH=.: $HADOOP_HOME /lib: $CLASSPATH

保存退出後使設置生效

1

source  /etc /profile

備註:HADOOP_HOME是HADOOP安裝路徑,請依據自己的情況修改。

2.4 格式化Hadoop

1

hadoop namenode –format

如過程中出現錯誤:Name or service not known

原因:/etc/sysconfig/network和/etc/hosts文件中的主機名不對應造成的,修改後重新格式化

繼續在命令行中輸入

1

start-all

來啓動Hadoop集羣

1
2
3
4
5

starting namenode, logging to  /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-namenode-master.out
slave: starting datanode, logging to  /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-datanode-slave.out
master: starting secondarynamenode, logging to  /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-secondarynamenode-master.out
starting jobtracker, logging to  /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-jobtracker-master.out
slave: starting tasktracker, logging to  /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-tasktracker-slave.out

通過日誌看出,Hadoop首先啓動namenode,接着啓動datanode……,然後啓動secondarynamenode;再啓動jobtracker,然後啓動tasktracker……hadoop成功啓動後,在 Master 中的 tmp 文件夾中生成了 dfs 文件夾,在Slave中的 tmp 文件夾中均生成了 dfs 文件夾和 mapred 文件夾。

1. 驗證方法一:用”jps”命令

在Master、Slave上用 java自帶的小工具jps查看進程。

如果系統提示“-bash: jps: command not found”,則表示JAVA的環境變量沒有配置好,依1.3檢查。

master的列表中應有“namenode”和“jobtracker”,slave的列表中應有”datanode”和”tasktracker”,如果沒有,可檢查日誌文件。

2、驗證方式二:用”hadoop dfsadmin -report”

用這個命令可以查看Hadoop集羣的狀態。包括可以快速定位出哪些節點down掉、HDFS的容量、使用了多少,以及每個節點的硬盤使用情況。

3、驗證方式三:http頁面端口監聽

在瀏覽器中輸入master:50030以及master:50070可查看HDFS和MapReduce狀態。備註:請注意“master:”,是作為namenode的主機名,如果是在本地搭建的偽分佈式,這裏可能是“localhost:50030”。

3 Hive配置

Hive是基於Hadoop構建的一套數據倉庫分析系統,它提供了豐富的SQL查詢方式來分析存儲在Hadoop 分佈式文件系統中的數據。其在Hadoop的架構體系中承擔了一個SQL解析的過程,它提供了對外的入口來獲取用户的指令然後對指令進行分析,解析出一個MapReduce程序組成可執行計劃,並按照該計劃生成對應的MapReduce任務提交給Hadoop集羣處理,獲取最終的結果。元數據——如表模式——存儲在名為metastore的數據庫中。

3.1 解壓Hive

安裝Hive的過程同安裝Hadoop的過程相似,也是先下載壓縮包並解壓。同樣,可先在master上安裝,然後分發到其他節點中。 登錄master 將Hive安裝包拷貝到home/hadoop/下並解壓

登錄master

將Hive安裝包拷貝到home/hadoop/下並解壓

1

tar –xzvf  /home /hadoop /apache-hive-0.13.1-bin.tar.gz

設置環境變量,Hive使用環境變量HADOOP_HOME來制定Hadoop的所有相關JAR和配置文件。

1
2
3

#set Hive environment
export  HIVE_HOME= /home /hadoop /apache-hive-0.13.1-bin
export  PATH$PATH$HIVE_HOME /bin

備註:HIVE_HOME的路徑設置為HIVE的安裝路徑,請依據自己的情況修改。

3.2 Metastore

metastore是Hive元數據集中存放地。它包括兩部分:服務和後台數據存儲。有三種方式配置metastore:內嵌metastore、本地metastore以及遠程metastore。

(1)默認情況下,metastore服務和hive服務運行在同一個JVM中,它包含一個內嵌的以本地磁盤作為存儲的Derby數據庫實例(也就是內嵌metastore)。但是,只使用一個內嵌Derby數據庫每次只能訪問一個磁盤上的數據庫文件。

(2)如果要支持多會話需要使用一個獨立的數據庫,即本地metastore。任何JDBC兼容的數據庫都可以通過一些配置屬性來用matastore使用。

(3)還有一種matastore配置成為遠程matastore,這種配置下,一個或多個matastore服務器和Hive服務運行在不同進程內,通過這種方式可將數據庫層完全置於防火牆後,從而更好得管理。

Hive沒有將matastore保存在HDFS上,而是保存在關係數據庫中是為了當Hive需要訪問matastore的時候,可低延遲的快速的訪問到需要的元數據信息(HDFS的訪問延遲一般都比較大)。但當HiveSQL之後生成的matastore任務在運行的時候如果需要訪問元數據信息時,並不會直接訪問matastore。當生成的物理計劃序列化到plan.xml的時候,就已將相應的元數據信息保存到了plan.xml中。而plan.xml文件之後會被放入Hadoop的分佈式緩存中,所以MapReduce任務就可以從分佈式緩存中獲得需要的元數據信息。 本文采用MySQL作為Hive的metastore。

登錄master

1、安裝MySQL(方法參考)

在安裝server的過程中會提示

1
2
3
4
5
6
7
8

PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER  !
To  do so, start the server,  then issue the following commands:

/usr /bin /mysqladmin  -u root password  'new-password'
/usr /bin /mysqladmin  -u root  -h master password  'new-password'

Alternatively you can run:
/usr /bin /mysql_secure_installation

2、設置root用户名及密碼

根據提示,待安裝完成後在命令行中輸入設置用户名(root)和密碼(hadoop)

1
2

/usr /bin /mysqladmin  -u root password hadoop
/usr /bin /mysqladmin  -u root  -h

在master用户下,用户名root,用户hadoop即可登錄

1

[hadoop @master ~ ]$ mysql  -uroot  -hmaster  -phadoop

如果可以登錄成功,則表示MySQL數據庫已經安裝成功

3、創建用户hive@master(密碼hive)並分配權限

1
2
3

CREATE USER  'hive' IDENTIFIED BY  'hive';
GRANT ALL PRIVILEGES ON  *. * TO  'hive' @ 'master' WITH GRANT OPTION;
flush privileges;

4、用户名hive登錄

1
2

mysql  -h master  -uhive
set password = password ( 'hive' );

5、建立 Hive 專用的元數據庫

1

create database hive;

6、其他可能會用到的命令

(1)查看MYSQL數據庫中所有用户

1

SELECT DISTINCT CONCAT ( 'User: ' '',user, '' '@' '',host, '' ';' )

(2)查看用户是否設置了密碼

1

mysql &gt ;;  select user,host,password from mysql.user;

3.3 配置Hive

Hive使用和Hadoop類似的XML配置文件進行設置,配置文件為hive/conf/hive-site.xml。幾個較為重要的metastore配置屬性見下表:

hive.metastore.warehouse.dir

相對於fs.default.name的目錄,託管表存儲在這裏

javax.jdo.option.ConnectionURL

metastore數據庫的JDBC URL

javax.jdo.option.ConnectionDriverName

JDBC驅動器的類名

javax.jdo.option.ConnectionUserName

JDBC用户名

javax.jdo.option.ConnectionConnectionPassword

JDBC密碼

1、修改配置文件

進入到hive的配置文件目錄下,找到hive-default.xml.template,另存為hive-site.xml並修改參數

1
2

cd hive-0.9.0-shark-0.8.0-bin /conf
vi hive-site.xml

Hive 系統會加載兩個配置文件一個默認配置文件“hive-default.xml”,另一個就是用户自定義文件“hive-site.xml”。當“hive-site.xml”中的配置參數的值與“hive-default.xml”文件中不一致時,以用户自定義的為準。所以可將不需要的參數都刪除掉,只留下下面所示的內容。

<?xml version=”1.0″?>

<?xml-stylesheet type=”text/xsl” href=”configuration.xsl”?>

<configuration>

<property>

<name>javax.jdo.option.ConnectionURL</name>

<value>jdbc:mysql://master:3306/hive?characterEncoding=UTF-8</value>

</property>

<property>

<name>javax.jdo.option.ConnectionDriverName</name>

<value>com.mysql.jdbc.Driver</value>

</property>

<property>

<name>javax.jdo.option.ConnectionUserName</name>

<value>hive</value>

</property>

<property>

<name>javax.jdo.option.ConnectionPassword</name>

<value>hive</value>

</property>

</configuration>

其中,MySQL的端口號3306為默認端口號,具體可在MySQL的配置文件my.cnf中查看。

2、拷貝JDBC驅動包

把MySQL的JDBC驅動包複製到Hive的lib目錄下(mysql-connector-java)

3、分發HIVE

完成後,拷貝Hive目錄到其他所有slave節點上,並且安裝目錄跟master上一致:

1

scp  -r  /home /hadoop /hadoop-1.2.1 / slave: /home /hadoop /

4、測試HIVE

拷貝完成後,嘗試測試下hive集羣是否搭建完成,在啓動hive之前,首先啓動hadoop集羣,然後再進入到hive安裝目錄下,執行命令:

1

bin /hive

如果可以正確顯示hive的命令行則表示安裝成功。

如提示:Cannot find hadoop installation: $HADOOP_HOME must be set or hadoop must be in the path

請檢查$HADOOP_HOME是否有打印信息

1

echo  $HADOOP_HOME

如無打印信息,請檢查~/.bash_profile中信息是否完整,並重新加載

1

source ~ /.bash_profile

若出現以下警告

1

WARN conf.HiveConf: DEPRECATED: Configuration property hive.metastore.local no longer has any effect. Make sure to provide a valid value  for hive.metastore.uris  if you are connecting to a remote megastore.

請檢查hive-site.xml中是否使用添加了

<property>

<name>hive.metastore.local</name>

<value>true</value>

</property>

在0.10 、0.11或者之後的HIVE版本 hive.metastore.local 屬性不再使用,請刪去。

5、測試:在Hive上建立數據表

1

hive&gt;  CREATE  TABLE xp (id  INT ,name string )  ROW FORMAT DELIMITED  FIELDS  TERMINATED  BY  '\t';
 2 )

6、從 MySQL 數據庫上查看元數據信息

用户Hive登錄MySQL

使用 hive 數據庫

1

use hive;

顯示 hive 數據庫中的數據表

1

show tables;

查看 hive 的元數據信息

1

select  *

備註:TBLS表中保存了所有hive表的基本信息

查看是否存在剛才建的那張表,如成功則Hive集成MySQL作為元數據庫已完成配置。

4 more about Hive

4.1 組成模塊

下圖顯示了Hive主要“模塊”以及Hive是如何與Hadoop交互工作的。圖片來自Programming Hive。

 

Hive發行版中附帶的模塊有CLI,一個成為Hive網頁界面(HWI)的簡單網頁界面,以及JDBC、ODBC和一個Thrift服務器這幾個模塊進行編程訪問。CLI也就是命令行界面,是和Hive交互的最常用方式。也是前文啓動Hive採用的方式,不過CLI的設計使其不通過編程的方式訪問。Thrift允許客户端使用包括JAVA、C++和其他多種語言,通過編程的方式訪問Hive。

所有的命令和查詢都會進入到Driver(驅動模塊)中,通過該模塊對輸入進行解析編譯,對需求的計算進行優化,然後按照指定的步驟執行。Hive通過和jobtracker通信來初始化MapReduce任務(job),在大型集羣中,通常會有網關機專門用於部署像Hive這樣的工具,在這些網關機上可遠程和管理節點上的jobtracker通信來執行任務(job)。通常要處理的數據文件是存儲在HDFS中的,而HDFS由namenode管理。metastore如前文所述是一個獨立的關係型數據庫,用以保存Hive表模式和其他系統元數據。

4.2 數據類型

Hive支持基本數據類型(Primitive Data Types)和集合數據類型(Collection Data Types Hive)。基本數據類型包括數值型、布爾型、字符串型等。複雜數據類型包括數組、映射和結構。Hive這些基本數據類型基本對應於Java中的類型,具體類型如下表所示:

類型

描述

TINYINT

1字節有符號整數,對應於Java的byte

SMALLINT

2字節有符號整數,對應於Java的short

INT

4字節有符號整數,對應於Java的int

BIGINT

8字節有符號整數,對應於Java的long

BOOLEAN

布爾型,true/false

FLOAT

單精度浮點數

DOUBLE

雙精度浮點數

STRING

存儲文本的數據類型,類似於其他數據庫的VACHAR

TIMESTAMP

UTC 時間,可用INT、FLOAT或STRING表示

BINARY

字節數組,與RDBMS中的 VARBINARY類型相似。可用以記錄任何字節,防止Hive將他們認做numbers或strings等

複合數據類型如下表:

類型

描述

ARRAY

一組有序字段,字段類型必須相同

MAP

一組無序的鍵-值對,鍵額類型必須為原子的,值可為任何類型。同一個映射的鍵的類型必須相同,值的類型也必須相同

STRUCT

一組命名的字段,字段的類型可不同

4.3 數據模型

Hive的數據模型包括database、table、partition和bucket。

數據模型

描述

數據庫(database)

相當於關係數據庫裏的命名空間(namespace),它的作用是將用户和數據庫的應用隔離到不同的數據庫或模式中。

表(table)

邏輯上由存儲的數據和描述表格中的數據形式的相關元數據組成。表存儲的數據一般存放在分佈式文件系統裏,如HDFS,但也可以是其他任何Hadoop文件系統中。元數據存儲在關係數據庫裏。在Hive中創建表時,默認情況下Hive負責管理數據,也就是將Hive數據移入它的“倉庫目錄”(warehouse directory),也可創建外部表(external table),讓Hive到倉庫目錄以外的位置訪問數據。

分區(partition)

Hive把表組織成“分區”,這是一種根據“分區列”(如日期)的值對錶的數據進行粗略劃分的機制。使用分區可以加快數據分片(slice)的查詢速度。

桶(bucket)

表和分區可以進一步分為“桶”,它會為數據提供額外的結構以獲得更高效的查詢處理。例如,可以根據用户ID來劃分桶,這則是對數據源數據文件本身來拆分數據。使用桶的表會將源數據文件按一定規律拆分成多個文件,要使用bucket,

 

4.4 HiveQL

是一種類SQL的Hive查詢語句(Hive query language)。它與大部分的SQL語法兼容,但是並不完全支持SQL標準,它最接近於MySQL的SQL,但也有明顯差別。如不支持行級插入、更新以及刪除,也不支持事務。各種關於創建、更新、刪除databases、tables、views、functions和indexes的語句以及各種數據操作方法這裏不詳細描述。

Hive DDL示例語句:

1
2
3
4
5
6
7

CREATE  [EXTERNAL ]  TABLE  [ IF  NOT  EXISTS ]  TABLE_NAME  (col_name data_type ,  ... )

[PARTITIONED  BY  (col_name data_type ,  ... ) ]

[  [ ROW FORMAT row_format ]  [STORED  AS file_format ]  |  [  WITH SERDEPROPERTIES  ( ... )  ]  ]

[LOCATION hdfs_path ]

關於HiveQL的查詢,以下簡單摘錄:

  1. SELECT…FROM語句

對於一個給定的記錄,SELECT指定了要保存額列以及輸出函數需要調用的一個或多個列。FROM子句標識了從哪個表、視圖或嵌套查詢中選擇記錄。

如查詢employees中所有員工的name和salary信息:

1

SELECT name , salary  FROM employees;

  1. WHERE語句

SELECT語句用於選取字段,WHERE語句用於過濾條件,兩者結合使用可找到符合過濾條件的記錄。WHERE語句使用謂詞表達式,當謂詞表達式計算結果為true時,相應的行將被保留並輸出。

如查詢employees中所有來自美國加利福利亞州的員工信息:

1
2
3

SELECT  *  FROM employees

WHERE country  =  'US'  AND state  =  'CA';

  1. GROUP BY

GROUP BY語句通常會和聚合函數一起使用,按照一個或多個列對結果進行分組,然後對每個組執行聚合操作。

如按照股票代碼為APPL的年份對股票記錄進行分組,然後計算每年的平均收盤價。

1
2
3
4
5

SELECT  YEAR (ymd ) , avg (price_close )  FROM stocks

WHERE exchange  =  'NASDAQ'  AND symbol  =  'AAPL'

GROUP  BY  YEAR (ymd );

  1. JOIN語句

Hive支持通常的SQL JOIN語句,但只支持等值連接。包括內連接、外連接、左外連接、右外連接、完全外連接、左半開連接、笛卡爾積、map端連接等。

1
2
3
4
5

SELECT a .ymd , a .price_close , b .price_close

FROM stocks a  JOIN stocks b  ON a .ymd  = b .ymd

WHERE a .symbol  =  'AAPL'  AND b .symbol  =  'IBM';

  1. ORDER BY和SORT BY

Hive中的ORDER BY語句和其他SQL中的定義是一樣的,其會對查詢結果集執行一個全局排序。換言之,所有數據都通過一個reduce進行處理,對於大數據集這會花費大量時間。Hive增加了一個SORT BY,其只會在每個reduce中對數據進行排序,即局部排序。這樣保證每個reduce的輸出都是有序的,可以提高之後全局排序的效率。

ORDER BY

1
2
3

SELECT s .ymd , s .symbol , s .price_close  FROM stocks s

ORDER  BY s .ymd  ASC , s .symbol  DESC;

SORT BY

1
2
3

SELECT s .ymd , s .symbol , s .price_close  FROM stocks s

SORT  BY s .ymd  ASC , s .symbol  DESC;

  1. 含有SORT BY的DISTRIBUTE BY

DISTRIBUTE BY控制map的輸出在reduce中如何劃分的。MapReduce job中傳輸的所有數據都是按照鍵-值對的方式進行組織,因此Hive在將用户的查詢語句轉換成MapReduce job時,其必須在內部使用此功能。

  1. CLUSTER BY

CLUSTER BY除了具有DISTRIBUTE BY的功能外還兼具SORT BY的功能。常常認為CLUSTER BY = DISTRIBUTE BY + SORT BY。但是排序只能是倒序排序,不能指定排序規則為asc 或者desc。

  1. 抽樣查詢

對於較大的數據集而只需要使用一個具有代表性結果的查詢結果時,可以通過Hive對錶進行分桶抽樣。

如,可使用rand()函數進行抽樣,函數會返回一個隨機值。

1

SELECT  *  FROM numbers TABLESAMPLE (BUCKET  3  OUT  OF  10  ON rand ( ) )

  1. UNION ALL

UNION ALL可以將2個或多個表進行合併,每個UNION子查詢都必須具有相同的列,而且對應的每個字段的字段類型必須一致。Hive也可用於同一個源表的數據合併。

如將日誌數據進行合併:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

SELECT log .ymd , log .level , log .message

FROM  (

SELECT l1 .ymd , l1 .level ,

l1 .message ,  'Log1'  AS  SOURCE

FROM log1 l1

UNION  ALL

SELECT l2 .ymd , l2 .level ,

l2 .message ,  'Log2'  AS  SOURCE

FROM log1 l2

) log

SORT  BY log .ymd  ASC;

4.5 元數據解析

在3.3中,通過在MySQL中輸入show table的語句,可以看到Hive元數據表,除了TBLS存儲表的基本信息,其他表的説明見下表:

BUCKETING_COLS

Hive表CLUSTERED BY字段信息(字段名,字段序號)

CDS

 

COLUMNS_V2

存放表格的字段信息

DATABASE_PARAMS

 

DBS

存放hive所有數據庫信息

FUNCS

 

FUNC_RU

 

GLOBAL_PRIVS

 

PARTITIONS

Hive表分區信息(創建時間,具體的分區)

PARTITION_KEYS

Hive分區表分區鍵(名稱,類型,comment,序號)

PARTITION_KEY_VALS

Hive表分區名(鍵值,序號)

PARTITION_PARAMS

 

PART_COL_STATS

 

ROLES

 

SDS

所有hive表、表分區所對應的hdfs數據目錄和數據格式。

SD_PARAMS

 

SEQUENCE_TABLE

SEQUENCE_TABLE表保存了hive對象的下一個可用ID,如’org.apache.hadoop.hive.metastore.model.MTable’, 21,則下一個新創建的hive表其TBL_ID就是21,同時SEQUENCE_TABLE表中271786被更新為26(這裏每次都是+5)。同樣,COLUMN,PARTITION等都有相應的記錄

SERDES

Hive表序列化反序列化使用的類庫信息

SERDE_PARAMS

序列化反序列化信息,如行分隔符、列分隔符、NULL的表示字符等

SKEWED_COL_NAMES

 

SKEWED_COL_VALUE_LOC_MAP

 

SKEWED_STRING_LIST

 

SKEWED_STRING_LIST_VALUES

 

SKEWED_VALUES

 

SORT_COLS

Hive表SORTED BY字段信息(字段名,sort類型,字段序號)

TABLE_PARAMS

表級屬性,如是否外部表,表註釋等

TAB_COL_STATS

 

TBLS

所有hive表的基本信息

VERSION

 

除了上面幾張表外,還有兩張表分別為:NUCLEUS_TABLES和SEQUENCE_TABLE。

其中,NUCLEUS_TABLES表中保存了元數據表和hive中class類的對應關係,SEQUENCE_TABLE表保存了hive對象的下一個可用ID。

通過這些信息,可以看出Hive創建表的過程。 1、解析用户提交hive語句,對其進行解析,分解為表、字段、分區等hive對象 2、根據解析到的信息構建對應的表、字段、分區等對象,從SEQUENCE_TABLE中獲取構建對象的最新ID,與構建對象信息(名稱,類型等)一同通過DAO方法寫入到元數據表中去,成功後將SEQUENCE_TABLE中對應的最新。

4.6 執行流程

如前所述,Hive是將HiveQL解析後生成了MapReduce的程序。換言之,客户端執行Hive 命令,輸入 HiveQL語句後,Hive將HiveQL語句生成多個 MR的job,然後將這些 job 提交給 Hadoop 進行執行,完成後,再把結果放入到 HDFS或者本地的臨時文件中。

這一過程的實現可使用EXPALIN命令查看,如:

1

hive &gt; EXPLAIN SELECT SUM (number )

這一執行流程主要涉及到的有語法解析器,語義分析器,邏輯計劃生成器,計劃優化器,物理計劃生成器,物理計劃執行器。

1、語法解析器

Hive利用antlr生成的HiveLexer.java和HiveParser.java類,將HiveQL轉換成ASTNode類型的語法樹。

2、語義分析器

根據語法解析器生成的語法樹(ASTNode),SemanticAnalyzerFactory會根據ASTNode的token類型生成不同的SemanticAnalyzer。ExplainSemanticAnalyzer、LoadSemanticAnalyzer、ExportSemanticAnalyzer、DDLSemanticAnalyzer、FunctionSemanticAnalyzer、SemanticAnalyzer6個子類。語義分析完成後,會將語句中的相應信息放入到org.apache.hadoop.hive.ql.plan包中 *Desc 類中,這些類記錄了相應語句的基本信息。

然後會對語義分析完了的信息進行驗證,比如表是否存在,字段是否存在,這時需要查詢元數據,同時將表的相關信息放到desc對象中。

3、邏輯計劃生成器

根據語義分析後的相關信息,將生成出邏輯操作樹,抽象類為Operator 。子類有:ExtractOperator、FilterOperator、ForwardOperator、GroupbyOperator、LateralViewJoinOperator、LimitOperator、MapOperator、ScriptOperator、SelectOperator、TableScanOperator、TerminalOperator-Base Class、FileSinkOperator、ReduceSinkOperator、UDTFOperator、UnionOperator。

4、邏輯計劃優化器

Hive會根據一定的rule來對生成的邏輯操作樹進行優化,在優化操作中會涉及到5個主要的對象,包括:Node、GraphWalker、Dispatcher、Rule和Processor。其中Node就代表DAG圖中的結點。

5、物理計劃生成器

通過genMapRedTasks,遞歸訪問邏輯操作樹,將裸機操作數轉換為一系列序列化的Map/Reduce工作。並將生成的計劃輸出到一個xml文件中。

6、物理計劃執行器

調用execute()方法完成相應的物理計劃執行工作。主要有FetchTask、ConditionalTask、CopyTask、DDLTask、ExplainTask、MapRedTask、MoveTask。