Hadoop學習筆記—17.Hive框架學習

Edison Chou發表於2015-04-19

一、Hive:一個牛逼的資料倉儲

1.1 神馬是Hive?

  Hive 是建立在 Hadoop 基礎上資料倉儲基礎構架。它提供了一系列的工具,可以用來進行資料提取轉化載入(ETL),這是一種可以儲存、查詢和分析儲存在 Hadoop 中的大規模資料的機制。Hive 定義了簡單的類 SQL  查詢語言,稱為 QL ,它允許熟悉 SQL  的使用者查詢資料。同時,這個語言也允許熟悉 MapReduce 開發者的開發自定義的 mapper  和 reducer 來處理內建的 mapper 和 reducer  無法完成的複雜的分析工作。

  Hive 是 SQL解析引擎,它將SQL語句轉譯成Map/Reduce Job然後在Hadoop執行。Hive的表其實就是HDFS的目錄,按表名把資料夾分開。如果是分割槽表,則分割槽值是子資料夾,可以直接在Map/Reduce Job裡使用這些資料。

1.2 Hive的系統結構

  由上圖可知,HDFS和Mapreduce是Hive架構的根基。Hive架構包括如下元件:CLI(command line interface)、JDBC/ODBC、Thrift Server、WEB GUI、metastore和Driver(Complier、Optimizer和Executor),這些元件可以分為兩大類:服務端元件客戶端元件

  (1)客戶端元件:

  ①CLI:command line interface,命令列介面。

  ②Thrift客戶端:上面的架構圖裡沒有寫上Thrift客戶端,但是Hive架構的許多客戶端介面是建立在Thrift客戶端之上,包括JDBC和ODBC介面。

  ③WEBGUI:Hive客戶端提供了一種通過網頁的方式訪問Hive所提供的服務。這個介面對應Hive的hwi元件(hive web interface),使用前要啟動hwi服務。

  (2)服務端元件:

  Driver元件:該元件包括Complier、Optimizer和Executor,它的作用是將我們寫的HiveQL(類SQL)語句進行解析、編譯優化,生成執行計劃,然後呼叫底層的mapreduce計算框架。

  ②Metastore元件:後設資料服務元件,這個元件儲存hive的後設資料,hive的後設資料儲存在關聯式資料庫裡,hive支援的關聯式資料庫有derby、mysql。後設資料對於hive十分重要,因此hive支援把metastore服務獨立出來,安裝到遠端的伺服器叢集裡,從而解耦hive服務和metastore服務,保證hive執行的健壯性

  ③Thrift服務:Thrift是facebook開發的一個軟體框架,它用來進行可擴充套件且跨語言的服務的開發,hive整合了該服務,能讓不同的程式語言呼叫hive的介面。

  (3)底層根基:

—>Hive 的資料儲存在 HDFS 中,大部分的查詢由 MapReduce 完成(包含 * 的查詢,比如 select * from table 不會生成 MapRedcue 任務)

二、Hive的基本安裝

2.1 準備工作

  (1)下載hive安裝包,這裡使用的是0.9.0版本,已經上傳到了網盤(http://pan.baidu.com/s/1sj0qnpV);

  (2)通過FTP工具上傳到虛擬機器hadoop-master中,可以是XShell、CuteFTP等工具;

2.2 開始安裝

  (1)解壓: tar -zvxf hive-0.9.0.tar.gz ,重新命名:mv hive-0.9.0 hive

  (2)加入環境變數配置檔案中:vim /etc/profile

export HIVE_HOME=/usr/local/hive

export PATH=.:$HADOOP_HOME/bin:$HIVE_HOME/bin:$PIG_HOME/bin:$HBASE_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$PATH  

  最後當然別忘了使環境變數生效:source /etc/profile

  (3)簡單配置Hive:進入$HIVE_HOME/conf目錄下,修改預設模板

Step 2.3.1:

在目錄$HIVE_HOME/conf/下,執行命令mv hive-default.xml.template hive-site.xml進行重新命名
在目錄$HIVE_HOME/conf/下,執行命令mv hive-env.sh.template hive-env.sh進行重新命名

Step 2.3.2:

修改hadoop的配置檔案hadoop-env.sh,修改內容如下:
  export HADOOP_CLASSPATH=.:$CLASSPATH:$HADOOP_CLASSPATH:$HADOOP_HOME/bin

在目錄$HIVE_HOME/bin下面,修改檔案hive-config.sh,增加以下內容:
  export JAVA_HOME=/usr/local/jdk
  export HIVE_HOME=/usr/local/hive
  export HADOOP_HOME=/usr/local/hadoop

  (4)簡單安裝MySQL:這裡使用的版本是5.5.31,已經上傳至了網盤(http://pan.baidu.com/s/1gdJ78aB

Step 2.4.1: 

刪除Linux上已經安裝的mysql相關庫資訊: rpm  -e  xxxxxxx   --nodeps

執行命令 rpm -qa |grep mysql 檢查是否刪除乾淨

Step 2.4.2: 

執行命令 rpm -i  MySQL-server-5.5.31-2.el6.i686.rpm  安裝mysql服務端

啟動 mysql 服務端,執行命令  mysqld_safe &

Step 2.4.3:

執行命令 rpm -i   MySQL-client-5.5.31-2.el6.i686.rpm  安裝mysql客戶端

執行命令 mysql_secure_installation 設定root使用者密碼

  (5)使用 MySQL 作為 Hive 的 metastore:

Step 2.5.1:

把mysql的jdbc驅動放置到hive的lib目錄下:cp mysql-connector-java-5.1.10.jar /usr/local/hive/lib

Step 2.5.2:

修改hive-site.xml檔案,修改內容如下: 

<property>
  <name>javax.jdo.option.ConnectionURL</name>
  <value>jdbc:mysql://hadoop-master:3306/hive?createDatabaseIfNotExist=true</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionDriverName</name>
  <value>com.mysql.jdbc.Driver</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionUserName</name>
  <value>root</value>
</property>
<property>
  <name>javax.jdo.option.ConnectionPassword</name>
  <value>admin</value>
</property>

三、Hive的基本使用

3.1 啟動Hadoop

  由1.2的圖可知,HDFS和Mapreduce是Hive架構的根基。因此,我們得先啟動Hadoop,才能正確使用Hive。

3.2 Hive的CLI命令列介面

  (1)內部表:與資料庫中的 Table 在概念上是類似,每一個 Table 在 Hive 中都有一個相應的目錄儲存資料。例如,一個表 test,它在 HDFS 中的路徑為:/ warehouse/test。 warehouse是在 hive-site.xml 中由 ${hive.metastore.warehouse.dir} 指定的資料倉儲的目錄;

建立表

hive>CREATE TABLE t1(id int); // 建立內部表t1,只有一個int型別的id欄位

hive>CREATE TABLE t2(id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'; // 建立內部表t2,有兩個欄位,它們之間通過tab分隔

載入資料
hive>LOAD DATA LOCAL INPATH '/root/id' INTO TABLE t1; // 從本地檔案載入
hive>LOAD DATA INPATH '/root/id' INTO TABLE t1; // 從HDFS中載入

檢視資料

hive>select * from t1; // 跟SQL語法類似

hive>select count(*) from t1; // hive也提供了聚合函式供使用

刪除表

hive>drop table t1;

  (2)分割槽表:所謂分割槽(Partition) 對應於資料庫的 Partition 列的密集索引。在 Hive 中,表中的一個 Partition 對應於表下的一個目錄,所有的 Partition 的資料都儲存在對應的目錄中。例如:test表中包含 date 和 city 兩個 Partition,則對應於date=20130201, city = bj 的 HDFS 子目錄為:/warehouse/test/date=20130201/city=bj。而對應於date=20130202, city=sh 的HDFS 子目錄為:/warehouse/test/date=20130202/city=sh。

建立表

hive>CREATE TABLE t3(id int) PARTITIONED BY (day int);

載入表
hive>LOAD DATA LOCAL INPATH '/root/id' INTO TABLE t1 PARTITION (day=22);

  (3)桶表(Hash 表):桶表是對資料進行雜湊取值,然後放到不同檔案中儲存。資料載入到桶表時,會對欄位取hash值,然後與桶的數量取模。把資料放到對應的檔案中。

建立表

hive>create table t4(id int) clustered by(id) into 4 buckets; // 建立一個桶表t4,根據id進行雜湊取值,並設定4個桶來儲存

設定允許進行分桶

hive>set hive.enforce.bucketing = true;

插入資料
hive>insert into table t4 select id from t3;

  (4)外部表:它和 內部表 在後設資料的組織上是相同的,而實際資料的儲存則有較大的差異。外部表主要指向已經在 HDFS 中存在的資料,可以建立 Partition。

  在HDFS中的external目錄下建立一個資料檔案:vim ids.txt

  建立一個外部表:hive>create external table t5(id int) location '/external';

外部表與內部表的差異:

①內部表 的建立過程和資料載入過程(這兩個過程可以在同一個語句中完成),在載入資料的過程中,實際資料會被移動到資料倉儲目錄中;之後對資料對訪問將會直接在資料倉儲目錄中完成。刪除表時,表中的資料和後設資料將會被同時刪除;
②外部表 只有一個過程,載入資料和建立表同時完成,並不會移動到資料倉儲目錄中,只是與外部資料建立一個連結。當刪除一個 外部表 時,僅刪除該連結;

  (5)檢視操作:和關聯式資料庫中的檢視一個概念,可以向使用者集中展現一些資料,遮蔽一些資料,提高資料庫的安全性。

建立檢視

hive> create view v1 as select * from t1;

查詢檢視

hive> select * from v1;

  (6)查詢操作:在Hive中,查詢分為三種:基於Partition的查詢、LIMIT Clause查詢、Top N查詢。

  ①基於Partition的查詢:一般 SELECT 查詢是全表掃描。但如果是分割槽表,查詢就可以利用分割槽剪枝(input pruning)的特性,類似“分割槽索引“”,只掃描一個表中它關心的那一部分。Hive 當前的實現是,只有分割槽斷言(Partitioned by)出現在離 FROM 子句最近的那個WHERE 子句中,才會啟用分割槽剪枝。例如,如果 page_views 表(按天分割槽)使用 date 列分割槽,以下語句只會讀取分割槽為‘2008-03-01’的資料。

SELECT page_views.*    FROM page_views    WHERE page_views.date >= '2013-03-01' AND page_views.date <= '2013-03-01'

   ②LIMIT Clause查詢:Limit 可以限制查詢的記錄數。查詢的結果是隨機選擇的。下面的查詢語句從 t1 表中隨機查詢5條記錄:

SELECT * FROM t1 LIMIT 5

  ③Top N查詢:和關係型資料中的Top N一樣,排序後取前N個顯示。下面的查詢語句查詢銷售記錄最大的 5 個銷售代表:

SET mapred.reduce.tasks = 1
SELECT * FROM sales SORT BY amount DESC LIMIT 5

  (7)連線操作:和關係型資料庫中的各種表連線操作一樣,在Hive中也可以進行表的內連線、外連線一類的操作:

匯入ac資訊表

hive> create table acinfo (name string,acip string)  row format delimited fields terminated by '\t' stored as TEXTFILE;

hive> load data local inpath '/home/acinfo/ac.dat' into table acinfo;

內連線

select b.name,a.* from dim_ac a join acinfo b on (a.ac=b.acip) limit 10;

左外連線

select b.name,a.* from dim_ac a left outer join acinfo b on a.ac=b.acip limit 10;

3.3 Hive的Java API介面

  (1)準備工作

  ①在伺服器端啟動Hive外部訪問服務(不是在hive命令列模式下,而是普通模式下):hive --service hiveserver >/dev/null  2>/dev/null &

  ②匯入Hive的相關jar包集合:

  (2)第一個Hive程式:讀取我們剛剛建立的內部表t1

package hive;

import java.sql.Statement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;

public class HiveApp {

    /**
     * 第一個hive java api程式
     * @throws Exception 
     */
    public static void main(String[] args) throws Exception {
        Class.forName("org.apache.hadoop.hive.jdbc.HiveDriver");
        Connection con = DriverManager.getConnection(
                "jdbc:hive://hadoop-master/default", "", "");
        Statement stmt = con.createStatement();
        String querySQL = "SELECT * FROM default.t1";

        ResultSet res = stmt.executeQuery(querySQL);

        while (res.next()) {
            System.out.println(res.getString(1));
        }
    }

}
View Code

  除錯結果:

四、Hive的執行流程

參考資料

(1)吳超,《深入淺出Hadoop》:http://www.superwu.cn/

(2)夏天的森林,《大資料時代的技術Hive:Hive介紹》:http://www.cnblogs.com/sharpxiajun/archive/2013/06/02/3114180.html

(3)哥不是小蘿莉,《那些年使用Hive踩過的坑》:http://www.cnblogs.com/smartloli/p/4288493.html

 

相關文章