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
|
vi etc /hosts
|
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
|
#set java environment
|
重新加載.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
|
cd ~ /.ssh
|
查看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
|
#set Hadoop environment
|
保存退出後使設置生效
|
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
|
starting namenode, logging to /home /hadoop /hadoop-1.2.1 /libexec /.. /logs /hadoop-hadoop-namenode-master.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
|
#set Hive environment
|
備註: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
|
PLEASE REMEMBER TO SET A PASSWORD FOR THE MySQL root USER !
|
2、設置root用户名及密碼
根據提示,待安裝完成後在命令行中輸入設置用户名(root)和密碼(hadoop)
|
1
|
/usr /bin /mysqladmin -u root password hadoop
|
在master用户下,用户名root,用户hadoop即可登錄
|
1 |
[hadoop @master ~ ]$ mysql -uroot -hmaster -phadoop |
如果可以登錄成功,則表示MySQL數據庫已經安裝成功
3、創建用户hive@master(密碼hive)並分配權限
|
1
|
CREATE USER 'hive' IDENTIFIED BY 'hive';
|
4、用户名hive登錄
|
1
|
mysql -h master -uhive
|
5、建立 Hive 專用的元數據庫
|
1 |
create database hive; |
6、其他可能會用到的命令
(1)查看MYSQL數據庫中所有用户
|
1 |
SELECT DISTINCT CONCAT ( 'User: ' '',user, '' '@' '',host, '' ';' ) |
(2)查看用户是否設置了密碼
|
1 |
mysql > ;; 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
|
cd hive-0.9.0-shark-0.8.0-bin /conf
|
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> 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
|
CREATE [EXTERNAL ] TABLE [ IF NOT EXISTS ] TABLE_NAME (col_name data_type , ... )
|
關於HiveQL的查詢,以下簡單摘錄:
- SELECT…FROM語句
對於一個給定的記錄,SELECT指定了要保存額列以及輸出函數需要調用的一個或多個列。FROM子句標識了從哪個表、視圖或嵌套查詢中選擇記錄。
如查詢employees中所有員工的name和salary信息:
|
1 |
SELECT name , salary FROM employees; |
- WHERE語句
SELECT語句用於選取字段,WHERE語句用於過濾條件,兩者結合使用可找到符合過濾條件的記錄。WHERE語句使用謂詞表達式,當謂詞表達式計算結果為true時,相應的行將被保留並輸出。
如查詢employees中所有來自美國加利福利亞州的員工信息:
|
1
|
SELECT * FROM employees
|
- GROUP BY
GROUP BY語句通常會和聚合函數一起使用,按照一個或多個列對結果進行分組,然後對每個組執行聚合操作。
如按照股票代碼為APPL的年份對股票記錄進行分組,然後計算每年的平均收盤價。
|
1
|
SELECT YEAR (ymd ) , avg (price_close ) FROM stocks
|
- JOIN語句
Hive支持通常的SQL JOIN語句,但只支持等值連接。包括內連接、外連接、左外連接、右外連接、完全外連接、左半開連接、笛卡爾積、map端連接等。
|
1
|
SELECT a .ymd , a .price_close , b .price_close
|
- ORDER BY和SORT BY
Hive中的ORDER BY語句和其他SQL中的定義是一樣的,其會對查詢結果集執行一個全局排序。換言之,所有數據都通過一個reduce進行處理,對於大數據集這會花費大量時間。Hive增加了一個SORT BY,其只會在每個reduce中對數據進行排序,即局部排序。這樣保證每個reduce的輸出都是有序的,可以提高之後全局排序的效率。
ORDER BY
|
1
|
SELECT s .ymd , s .symbol , s .price_close FROM stocks s
|
SORT BY
|
1
|
SELECT s .ymd , s .symbol , s .price_close FROM stocks s
|
- 含有SORT BY的DISTRIBUTE BY
DISTRIBUTE BY控制map的輸出在reduce中如何劃分的。MapReduce job中傳輸的所有數據都是按照鍵-值對的方式進行組織,因此Hive在將用户的查詢語句轉換成MapReduce job時,其必須在內部使用此功能。
- CLUSTER BY
CLUSTER BY除了具有DISTRIBUTE BY的功能外還兼具SORT BY的功能。常常認為CLUSTER BY = DISTRIBUTE BY + SORT BY。但是排序只能是倒序排序,不能指定排序規則為asc 或者desc。
- 抽樣查詢
對於較大的數據集而只需要使用一個具有代表性結果的查詢結果時,可以通過Hive對錶進行分桶抽樣。
如,可使用rand()函數進行抽樣,函數會返回一個隨機值。
|
1 |
SELECT * FROM numbers TABLESAMPLE (BUCKET 3 OUT OF 10 ON rand ( ) ) |
- UNION ALL
UNION ALL可以將2個或多個表進行合併,每個UNION子查詢都必須具有相同的列,而且對應的每個字段的字段類型必須一致。Hive也可用於同一個源表的數據合併。
如將日誌數據進行合併:
|
1
|
SELECT log .ymd , log .level , log .message
|
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 > 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。