hive簡介


http://www.51niux.com/

一、Hive介紹

Hive官網:https://hive.apache.org/

1.1 hive簡介

        Hive是一個數據倉庫基礎工具在Hadoop中用來處理結構化數據。它架構在Hadoop之上,總歸為大數據,並使得查詢和分析方便。並提供簡單的sql查詢功能,可以將sql語句轉換為MapReduce任務進行運行。

        最初,Hive是由Facebook開發,后來由Apache軟件基金會開發,並作為進一步將它作為名義下Apache Hive為一個開源項目。Hive 沒有專門的數據格式。 Hive 可以很好的工作在 Thrift 之上,控制分隔符,也允許用戶指定數據格式。Hive不適用於在線事務處理。 它最適用於傳統的數據倉庫任務。

       Hive 構建在基於靜態批處理的Hadoop 之上,Hadoop 通常都有較高的延遲並且在作業提交和調度的時候需要大量的開銷。因此,Hive 並不能夠在大規模數據集上實現低延遲快速的查詢,例如,Hive 在幾百MB 的數據集上執行查詢一般有分鍾級的時間延遲。因此,
      Hive 並不適合那些需要低延遲的應用,例如,聯機事務處理(OLTP)。Hive 查詢操作過程嚴格遵守Hadoop MapReduce 的作業執行模型,Hive 將用戶的HiveQL 語句通過解釋器轉換為MapReduce 作業提交到Hadoop 集群上,Hadoop 監控作業執行過程,然后返回作業執行結果給用戶。Hive 並非為聯機事務處理而設計,Hive 並不提供實時的查詢和基於行級的數據更新操作。Hive 的最佳使用場合是大數據集的批處理作業,例如,網絡日志分析。

1.2 Hive的特點:

 

  1. 通過SQL輕松訪問數據的工具,從而實現數據倉庫任務(如提取/轉換/加載(ETL),報告和數據分析)。

  2. 一種對各種數據格式施加結構的機制

  3. 訪問直接存儲在Apache HDFS或其他數據存儲系統(如Apache HBase)中的文件

  4. 通過Apache Tez,Apache Spark或MapReduce執行查詢

  5. 程序語言與HPL-SQL

  6. 通過Hive LLAP,Apache YARN和Apache Slider進行亞秒級查詢檢索。

Bash
Hive提供了標准的SQL功能,其中包括許多后來用於分析的SQL:2003和SQL:2011功能。
Hive的SQL還可以通過用戶定義的函數(UDF),用戶定義的聚合(UDAF)和用戶定義的表函數(UDTF)用用戶代碼進行擴展。
沒有一個數據必須存儲的“Hive格式”。 Hive帶有用於逗號和制表符分隔值(CSV / TSV)文本文件,Apache Parquet,Apache ORC和其他格式的內置連接器。用戶可以使用其他格式的連接器來擴展Hive。
Hive不適用於聯機事務處理(OLTP)工作負載。它最適用於傳統的數據倉庫任務。
Hive旨在最大限度地提高可伸縮性(在Hadoop集群中動態添加更多機器的規模),性能,可擴展性,容錯性以及與輸入格式的松散耦合。
Hive的組件包括HCatalog和WebHCat。
HCatalog是Hive的一個組件。這是Hadoop的表和存儲管理層,使用不同數據處理工具(包括Pig和MapReduce)的用戶可以更方便地在網格上讀寫數據。
WebHCat提供的服務可以用來運行Hadoop MapReduce(或YARN),Pig,Hive作業或使用HTTP(REST風格)接口執行Hive元數據操作。

1.3 Hive架構與基本組成

圖片.png

Hive的體系結構:

#上圖為Hive的體系結構,可以分為以下幾個部分:

  1. 用戶接口主要有三個:CLI,Client和WUI.其中最常用的是CLI,CLI啟動的時候,會同時啟動一個Hive副本。Client是Hive的客戶端,用戶連接至Hive Server。在啟動Client模式的時候,需要指出Hive Server所在節點,並且在該節點啟動Hive Server。WUI是通過瀏覽器訪問Hive。

  2. Hive將元數據存儲在數據庫中,如mysql、derby。Hive中的元數據包括表的名字,表的列和分區以及屬性,表的屬性(是否為外部表等),表的數據所在目錄等。

  3. 解釋器、編輯器、優化器完成HQL查詢語句從詞法分析、語法分析、編譯、優化以及查詢計划的生成。生成的查詢計划存儲在HDFS中,並在隨后有MapReduce調用執行。

  4. Hive的數據存儲在HDFS中,大部分的查詢、計算由MapReduce完成。

服務端和客戶端組件:

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

服務端組件:

Bash
Driver組件:該組件包括Complier、Optimizer和Executor,它的作用是將我們寫的HiveQL(類SQL)語句進行解析、編譯優化,生成執行計划,然后調用底層的mapreduce計算框架。
Metastore組件:元數據服務組件,這個組件存儲hive的元數據,hive的元數據存儲在關系數據庫里,hive支持的關系數據庫有derby、mysql。元數據對於hive十分重要,因此hive支持把metastore服務獨立出來,安裝到遠程的服務器集群里,從而解耦hive服務和metastore服務,保證hive運行的健壯性,這個方面的知識,我會在后面的metastore小節里做詳細的講解。
Thrift服務:thrift是facebook開發的一個軟件框架,它用來進行可擴展且跨語言的服務的開發,hive集成了該服務,能讓不同的編程語言調用hive的接口。

客戶端組件:

Bash
 CLI:command line interface,命令行接口。
 Thrift客戶端:上面的架構圖里沒有寫上Thrift客戶端,但是hive架構的許多客戶端接口是建立在thrift客戶端之上,包括JDBC和ODBC接口。
 WEBGUI:hive客戶端提供了一種通過網頁的方式訪問hive所提供的服務。這個接口對應hive的hwi組件(hive web interface),使用前要啟動hwi服務。

Hive的metastore組件

      Hive的metastore組件是hive元數據集中存放地。Metastore組件包括兩個部分:metastore服務和后台數據的存儲。后台數據存儲的介質就是關系數據庫,例如hive默認的嵌入式磁盤數據庫derby,還有mysql數據庫。Metastore服務是建立在后台數據存儲介質之上,並且可以和hive服務進行交互的服務組件,默認情況下,metastore服務和hive服務是安裝在一起的,運行在同一個進程當中。我也可以把metastore服務從hive服務里剝離出來,metastore獨立安裝在一個集群里,hive遠程調用metastore服務,這樣我們可以把元數據這一層放到防火牆之后,客戶端訪問hive服務,就可以連接到元數據這一層,從而提供了更好的管理性和安全保障。使用遠程的metastore服務,可以讓metastore服務和hive服務運行在不同的進程里,這樣也保證了hive的穩定性,提升了hive服務的效率。

連接到數據庫的模式:

有三種模式可以連接到數據庫:

  1. 單用戶模式。此模式連接到一個In-memory 的數據庫Derby,一般用於Unit Test。

  2. 多用戶模式。通過網絡連接到一個數據庫中,是最經常使用到的模式。

  3. 遠程服務器模式。用於非Java客戶端訪問元數據庫,在服務器端啟動MetaStoreServer,客戶端利用Thrift協議通過MetaStoreServer訪問元數據庫。

Bash
 對於數據存儲,Hive沒有專門的數據存儲格式,也沒有為數據建立索引,用戶可以非常自由的組織Hive中的表,只需要在創建表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就可以解析數據。
 Hive中所有的數據都存儲在HDFS中,存儲結構主要包括數據庫、文件、表和視圖。Hive中包含以下數據模型:Table內部表,External Table外部表,Partition分區,Bucket桶。
 Hive默認可以直接加載文本文件,還支持sequence file 、RCFile。

Hive的數據模型介紹:

官網介紹:https://cwiki.apache.org/confluence/display/Hive/Tutorial

  1. Hive數據庫。 類似傳統數據庫的DataBase,在第三方數據庫里實際是一張表。簡單示例命令行 hive > create database test_database;

  2. 內部表。 Hive的內部表與數據庫中的Table在概念上是類似。每一個Table在Hive中都有一個相應的目錄存儲數據。例如一個表pvs,它在HDFS中的路徑為/wh/pvs,其中wh是在hive-site.xml中由${hive.metastore.warehouse.dir} 指定的數據倉庫的目錄,所有的Table數據(不包括External Table)都保存在這個目錄中。刪除表時,元數據與數據都會被刪除。 內部表簡單示例如下:

Bash
    創建數據文件:test_inner_table.txt
    創建表:create table test_inner_table (key string) 加載數據:LOAD DATA LOCAL INPATH ‘filepath’ INTO TABLE test_inner_table 查看數據:select * from test_inner_table; select count(*) from test_inner_table 刪除表:drop table test_inner_table

   3. 外部表。 外部表指向已經在HDFS中存在的數據,可以創建Partition。它和內部表在元數據的組織上是相同的,而實際數據的存儲則有較大的差異。內部表的創建過程和數據加載過程這兩個過程可以分別獨立完成,也可以在同一個語句中完成,在加載數據的過程中,實際數據會被移動到數據倉庫目錄中;之后對數據對訪問將會直接在數據倉庫目錄中完成。刪除表時,表中的數據和元數據將會被同時刪除。而外部表只有一個過程,加載數據和創建表同時完成(CREATE EXTERNAL TABLE ……LOCATION),實際數據是存儲在LOCATION后面指定的 HDFS 路徑中,並不會移動到數據倉庫目錄中。當刪除一個External Table時,僅刪除該鏈接。 外部表簡單示例:

Bash
    創建數據文件:test_external_table.txt
    創建表:create external table test_external_table (key string) 加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_inner_table 查看數據:select * from test_external_table; •select count(*) from test_external_table 刪除表:drop table test_external_table

  4.  分區。  Partition對應於數據庫中的Partition列的密集索引,但是Hive中Partition的組織方式和數據庫中的很不相同。在Hive中,表中的一個Partition對應於表下的一個目錄,所有的Partition的數據都存儲在對應的目錄中。例如pvs表中包含ds和city兩個Partition,則對應於ds = 20090801, ctry = US 的HDFS子目錄為/wh/pvs/ds=20090801/ctry=US;對應於 ds = 20090801, ctry = CA 的HDFS子目錄為/wh/pvs/ds=20090801/ctry=CA。分區表簡示例

Bash
    創建數據文件:test_partition_table.txt
    創建表:create table test_partition_table (key string) partitioned by (dt string) 加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_partition_table partition (dt=‘2006’) 查看數據:select * from test_partition_table; select count(*) from test_partition_table 刪除表:drop table test_partition_table

 5. 桶 。Buckets是將表的列通過Hash算法進一步分解成不同的文件存儲。它對指定列計算hash,根據hash值切分數據,目的是為了並行,每一個Bucket對應一個文件。例如將user列分散至32個bucket,首先對user列的值計算hash,對應hash值為0的HDFS目錄為/wh/pvs/ds=20090801/ctry=US/part-00000;hash值為20的HDFS目錄為/wh/pvs/ds=20090801/ctry=US/part-00020。如果想應用很多的Map任務這樣是不錯的選擇。 桶的簡單示例:

Bash
    創建數據文件:test_bucket_table.txt
    創建表:create table test_bucket_table (key string) clustered by (key) into 20 buckets 加載數據:LOAD DATA INPATH ‘filepath’ INTO TABLE test_bucket_table 查看數據:select * from test_bucket_table; set hive.enforce.bucketing = true;

 6. Hive的視圖。視圖與傳統數據庫的視圖類似。視圖是只讀的,它基於的基本表,如果改變,數據增加不會影響視圖的呈現;如果刪除,會出現問題。如果不指定視圖的列,會根據select語句后的生成。示例:

Bash
    create view test_view as select * from test

1.4 Hive和數據庫的異同:

       由於Hive采用了SQL的查詢語言HQL,因此很容易將Hive理解為數據庫。其實從結構上來看,Hive和數據庫除了擁有類似的查詢語言,再無類似之處。數據庫可以用在Online的應用中,但是Hive是為數據倉庫而設計的,清楚這一點,有助於從應用角度理解Hive的特性。Hive和數據庫的比較如下表:

圖片.png

#從上如可以看到它們之間的差別。

  1. 查詢語言。由於 SQL 被廣泛的應用在數據倉庫中,因此專門針對Hive的特性設計了類SQL的查詢語言HQL。熟悉SQL開發的開發者可以很方便的使用Hive進行開發。

  2. 數據存儲位置。Hive是建立在Hadoop之上的,所有Hive的數據都是存儲在HDFS中的。而數據庫則可以將數據保存在塊設備或者本地文件系統中。

  3. 數據格式。Hive中沒有定義專門的數據格式,數據格式可以由用戶指定,用戶定義數據格式需要指定三個屬性:列分隔符(通常為空格、”\t”、”\x001″)、行分隔符(”\n”)以及讀取文件數據的方法(Hive中默認有三個文件格式TextFile,SequenceFile以及RCFile)。由於在加載數據的過程中,不需要從用戶數據格式到Hive定義的數據格式的轉換,因此,
    Hive在加載的過程中不會對數據本身進行任何修改,而只是將數據內容復制或者移動到相應的HDFS目錄中。
    而在數據庫中,不同的數據庫有不同的存儲引擎,定義了自己的數據格式。所有數據都會按照一定的組織存儲,因此,數據庫加載數據的過程會比較耗時。

  4. 數據更新。由於Hive是針對數據倉庫應用設計的,而數據倉庫的內容是讀多寫少的。因此,Hive中不支持對數據的改寫和添加,所有的數據都是在加載的時候中確定好的。而數據庫中的數據通常是需要經常進行修改的,因此可以使用INSERT INTO ... VALUES添加數據,使用UPDATE ... SET修改數據。

  5. 索引。之前已經說過,Hive在加載數據的過程中不會對數據進行任何處理,甚至不會對數據進行掃描,因此也沒有對數據中的某些Key建立索引。Hive要訪問數據中滿足條件的特定值時,需要暴力掃描整個數據,因此訪問延遲較高。由於MapReduce的引入, Hive可以並行訪問數據,因此即使沒有索引,對於大數據量的訪問,Hive仍然可以體現出優勢。數據庫中,通常會針對一個或者幾個列建立索引,因此對於少量的特定條件的數據的訪問,數據庫可以有很高的效率,較低的延遲。由於數據的訪問延遲較高,決定了Hive不適合在線數據查詢。

  6. 執行。Hive中大多數查詢的執行是通過Hadoop提供的MapReduce來實現的(類似select * from tbl的查詢不需要MapReduce)。而數據庫通常有自己的執行引擎。

  7. 執行延遲。之前提到,Hive在查詢數據的時候,由於沒有索引,需要掃描整個表,因此延遲較高。另外一個導致Hive執行延遲高的因素是MapReduce框架。由於MapReduce本身具有較高的延遲,因此在利用MapReduce執行Hive查詢時,也會有較高的延遲。相對的,數據庫的執行延遲較低。當然,這個低是有條件的,即數據規模較小,當數據規模大到超過數據庫的處理能力的時候,Hive的並行計算顯然能體現出優勢。

  8. 可擴展性。由於Hive是建立在Hadoop之上的,因此Hive的可擴展性是和Hadoop的可擴展性是一致的。而數據庫由於ACID語義的嚴格限制,擴展行非常有限。

  9. 數據規模。由於Hive建立在集群上並可以利用MapReduce進行並行計算,因此可以支持很大規模的數據;對應的,數據庫可以支持的數據規模較小。

1.5 Hive工作原理

圖片.png

#上圖描述了Hive和Hadoop之間的工作流程,下面是Hive和Hadoop框架的交互方式:

Hive和Hadoop框架的交互方式:

  1. Execute Query。Hive接口,如命令行或Web UI發送查詢驅動程序(任何數據庫驅動程序,如JDBC,ODBC等)來執行。

  2. Get Plan。在驅動程序幫助下查詢編譯器,分析查詢檢查語法和查詢計划或查詢的要求。

  3. Get Metadata。編譯器發送元數據請求到Metastore(任何數據庫)。

  4. Send Metadata。Metastore發送元數據,以編譯器的響應。

  5. Send Plan。編譯器檢查要求,並重新發送計划給驅動程序。到此為止,查詢解析和編譯完成。

  6. Execute Plan。驅動程序發送的執行計划到執行引擎。

  7. Execute Job。在內部,執行作業的過程是一個MapReduce工作。執行引擎發送作業給JobTracker,在名稱節點並把它分配作業到TaskTracker,這是在數據節點。在這里,查詢執行MapReduce工作。(7.1 Metadata Ops:與此同時,在執行時,執行引擎可以通過Metastore執行元數據操作。)

  8. Fetch Result. 執行引擎接收來自數據節點的結果。

  9. Send Results. 執行引擎發送這些結果值給驅動程序。

  10. Send Results。驅動程序將結果發送給Hive接口。

執行過程就是:

Bash
HiveQL通過CLI/web UI或者thrift 、 odbc 或 jdbc接口的外部接口提交,經過complier編譯器,運用Metastore中的元數據進行類型檢測和語法分析,生成一個邏輯方案(logical plan),然后通過簡單的優化處理,產生一個以有向無環圖DAG數據結構形式展現的map-reduce任務。

Hive構建在Hadoop之上,Hive的執行原理:

  1. HQL中對查詢語句的解釋、優化、生成查詢計划是由Hive完成的

  2. 所有的數據都是存儲在Hadoop中

  3. 查詢計划被轉化為MapReduce任務,在Hadoop中執行(有些查詢沒有MR任務,如:select * from table)

  4. Hadoop和Hive都是用UTF-8編碼的

查詢編譯器(query complier),用雲存儲中的元數據來生成執行計划,步驟如下:

  1. 解析(parse)-anlr解析其生成語法樹AST(hibernate也是這個):將HQL轉化為抽象語法樹AST

  2. 類型檢查和語法分析(type checking and semantic analysis):將抽象語法樹轉換此查詢塊(query block tree),並將查詢塊轉換成邏輯查詢計划(logic plan Generator);

  3. 優化(optimization):重寫查詢計划(logical optimizer)–>將邏輯查詢計划轉成物理計划(physical plan generator)–>選擇最佳的join策略(physical optimizer)

博文來自:www.51niux.com

二、Hive的安裝

2.1 Hive的下載並解壓到指定位置

hadoop的安裝前面已經說過了,注意:Hive版本1.2以上需要Java 1.7或更高版本。 Hive版本0.14到1.1也適用於Java 1.6。 強烈建議用戶開始轉向Java 1.8。Hadoop 2.x(首選),1.x(不支持Hive 2.0.0以上版本)。
Hive版本0.13也支持Hadoop 0.20.x,0.23.x。Hive常用於生產Linux和Windows環境。 Mac是一個常用的開發環境。

#Hadoop集群的搭建前面已經介紹了,現在再次基礎上安裝Hive。

# wget mirrors.hust.edu.cn/apache/hive/stable/apache-hive-1.2.2-bin.tar.gz

# tar zxf apache-hive-1.2.2-bin.tar.gz  -C /home/hadoop/
# ln -s /home/hadoop/apache-hive-1.2.2-bin /home/hadoop/apache-hive
# vim /etc/profile

Bash
##########hive################# export HIVE_HOME=/home/hadoop/apache-hive export PATH=$PATH:$HIVE_HOME/bin

# source /etc/profile

2.2 Metastore安裝

Bash
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。

#這里我們選擇搭建一台節點搭建mysql服務器來存儲這些元數據。

#mysql的搭建可以yum可以編譯這里就不寫安裝過程了。我線上是編譯的,這里為了快速就yum安裝了。

#vi  /etc/my.cnf  #加上下面兩句

Bash
[mysqld] skip-name-resolve #參數的目的是不再進行反解析(ip不反解成域名),這樣可以加快數據庫的反應時間。 sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES #默認用的是嚴格模式,mysql 5.6默認用innodb ,所以用STRICT_TRANS_TABLES也容易理解。用了這個選項的話, 那么數據庫中如果是非空值的話就得設置默認值了,否則是報錯的

# service mariadb start  #啟動mysqld服務

# mysqladmin -u root password '123456'  #更改root的密碼,應該復雜一點

# mysql -uroot -p123456 -e "show databases;"  #查看一下是否生效

# mysql -uroot -p123456  #登錄mysql做個hadoop用戶授權

Bash
MariaDB [(none)]> create database hive; MariaDB [(none)]> grant all privileges on hive.* to hive@"192.168.14.%" identified by 'hive'; #如果hive服務端不在本機要設置這么一條 MariaDB [(none)]> grant all privileges on hive.* to hive@localhost identified by 'hive'; MariaDB [(none)]> flush privileges; MariaDB [(none)]> exit

# mysql -uhive -phive -h 192.168.14.49 -e "show databases;"  #分別驗證一下。
# mysql -uhive -phive -h localhost -e "show databases;"

2.3 下載JDBC驅動

# wget https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.31.tar.gz
# tar zxf mysql-connector-java-5.1.31.tar.gz
# cp mysql-connector-java-5.1.31/mysql-connector-java-5.1.31-bin.jar /home/hadoop/apache-hive/lib/

2.4 配置Hive配置文件

# cp /home/hadoop/apache-hive/conf/hive-env.sh.template  /home/hadoop/apache-hive/conf/hive-env.sh
# vim /home/hadoop/apache-hive/conf/hive-env.sh

Bash
# export HADOOP_HEAPSIZE=1024 export HADOOP_HEAPSIZE=10240 # HADOOP_HOME=${bin}/../../hadoop export HADOOP_HOME=/home/hadoop/hadoop # export HIVE_CONF_DIR= export HIVE_CONF_DIR=/home/hadoop/apache-hive/conf export HADOOP_CLIENT_OPTS="$HADOOP_CLIENT_OPTS -Xmx${HADOOP_HEAPSIZE}m -XX:PermSize=256m -XX:MaxPermSize=4096m"

# vim /home/hadoop/apache-hive/conf/hive-site.xml   #這里直接編輯了,查看詳細配置可以查看/home/hadoop/apache-hive/conf/hive-default.xml.template

Bash
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml-stylesheet type="text/xsl" href="configuration.xsl"?><!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> <configuration> <!--Hive的元數據庫,這是連接master.hadoop:3306端口的hive數據庫,如果庫不存在就可以創建--> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://master.hadoop:3306/hive?createDatabaseIfNotExist=true</value> </property> <!--連接元數據的驅動名--> <property> <name>javac.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> <!--表示數據在hdfs中的存儲位置--> <property> <name>hive.metastore.warehouse.dir</name> <value>hdfs://mycluster/user/hive/warehouse</value> </property> <!--動態分區的模式,默認strict,表示必須指定至少一個分區為靜態分區,nonstrict模式表示允許所有的分區字段都可以使用動態分區。--> <property> <name>hive.exec.dynamic.partition.mode</name> <value>nonstrict</value> </property> <!--默認情況下,HiveServer2以提交查詢的用戶執行查詢(true),如果hive.server2.enable.doAs設置為false,查詢將以運行hiveserver2進程的用戶運行。--> <property> <name>hive.server2.enable.doAs</name> <value>false</value> </property> <!-- hive.metastore.schema.verification值為false即可解決“Caused by: MetaException(message:Version information not found in metastore.)”--> <property> <name>hive.metastore.schema.verification</name> <value>false</value> </property> </configuration>

# chown -R hadoop:hadoop /home/hadoop/apache-hive-1.2.2-bin

$ /home/hadoop/apache-hive/bin/schematool -dbType mysql -initSchema   #在mysql中初始化hive的schema

Bash
Metastore connection URL:     jdbc:mysql://master.hadoop:3306/hive?createDatabaseIfNotExist=true Metastore Connection Driver : org.apache.derby.jdbc.EmbeddedDriver Metastore connection User: hive Starting metastore schema initialization to 1.2.0 Initialization script hive-schema-1.2.0.mysql.sql Initialization script completed schemaTool completed

# mysql -uroot -p123456 -e "use hive;show tables;"   #查看一下hive庫里面產生了一堆元數據相關的表

Bash
+---------------------------+
| Tables_in_hive | +---------------------------+ | BUCKETING_COLS | | CDS | | COLUMNS_V2 | | COMPACTION_QUEUE | | COMPLETED_TXN_COMPONENTS | | DATABASE_PARAMS | | DBS | | DB_PRIVS | | DELEGATION_TOKENS | | FUNCS | | FUNC_RU | | GLOBAL_PRIVS | | HIVE_LOCKS | | IDXS | | INDEX_PARAMS | | MASTER_KEYS | | NEXT_COMPACTION_QUEUE_ID | | NEXT_LOCK_ID | | NEXT_TXN_ID | | NOTIFICATION_LOG | | NOTIFICATION_SEQUENCE | | NUCLEUS_TABLES | | PARTITIONS | | PARTITION_EVENTS | | PARTITION_KEYS | | PARTITION_KEY_VALS | | PARTITION_PARAMS | | PART_COL_PRIVS | | PART_COL_STATS | | PART_PRIVS | | ROLES | | ROLE_MAP | | SDS | | SD_PARAMS | | SEQUENCE_TABLE | | SERDES | | SERDE_PARAMS | | SKEWED_COL_NAMES | | SKEWED_COL_VALUE_LOC_MAP | | SKEWED_STRING_LIST | | SKEWED_STRING_LIST_VALUES | | SKEWED_VALUES | | SORT_COLS | | TABLE_PARAMS | | TAB_COL_STATS | | TBLS | | TBL_COL_PRIVS | | TBL_PRIVS | | TXNS | | TXN_COMPONENTS | | TYPES | | TYPE_FIELDS | | VERSION | +---------------------------+

博文來自:www.51niux.com

2.5 進入hive shell測試

$ /home/hadoop/apache-hive/bin/hive

Bash
ls: 無法訪問/home/hadoop/spark/lib/spark-assembly-*.jar: 沒有那個文件或目錄
Logging initialized using configuration in file:/home/hadoop/apache-hive-1.2.2-bin/conf/hive-log4j.properties hive>

#上面的ls: 無法訪問/home/hadoop/spark/lib/spark-assembly-*.jar: 沒有那個文件或目錄要解決一下:

Bash
其主要的原因是:在hive.sh的文件中,發現了這樣的命令,原來初始當spark存在的時候,進行spark中相關的JAR包的加載。
而自從spark升級到2.0.0之后,原有的lib的整個大JAR包已經被分散的小JAR包的替代,所以肯定沒有辦法找到這個spark-assembly的JAR包。這就是問題所在。

解決:

$ vim /home/hadoop/apache-hive/bin/hive

Bash
 #sparkAssemblyPath=`ls ${SPARK_HOME}/lib/spark-assembly-*.jar` #上面的注釋掉改為下面的那句話 sparkAssemblyPath=`ls ${SPARK_HOME}/jars/*.jar`

$ hive

Bash
hive> CREATE SCHEMA testdb; OK Time taken: 1.131 seconds hive> SHOW DATABASES; OK default testdb Time taken: 0.307 seconds, Fetched: 2 row(s) hive> quit; #退出

2.6 Hive服務端的啟動

#$ hive --service metastore &    #要啟動metastore服務

$  /home/hadoop/apache-hive/bin/hive --service metastore >/home/hadoop/apache-hive/hive_metastore.log 2>&1   #當然更好的方式是指定日志后台啟動

$ jps

Bash
17420 RunJar   #多了一個進程

$ netstat  -lntup|grep 9083   #默認啟動的是9083端口

Bash
tcp        0      0 0.0.0.0:9083            0.0.0.0:*               LISTEN      17420/java

2.7 Hive客戶端的測試

#注意:我這里測試是有問題的,跟生產是不符的,如果直接hive shell操作,是不用啟動Runjar這個進程的,直接配置文件指定了mysql的數據庫用戶名密碼什么的就可以操作了。啟動RunJar這個進程服務,啟動9083端口或者下面提到的10000端口,都是為了讓其他的客戶端工具(例如spark)來使用hive讀寫hdfs上面的數據,才需要下面的hive-site.xml配置。

$scp -r /home/hadoop/apache-hive-1.2.2-bin 192.168.14.52:/home/hadoop/  #發送到一個datanode客戶端

$ vim /home/hadoop/apache-hive-1.2.2-bin/conf/hive-site.xml  #客戶端的配置文件修改成下面的內容

Bash
<configuration> <property> <name>hive.metastore.uris</name> <value>thrift://master.hadoop:9083</value> </property> </configuration>

[hadoop@smaster conf] $ /home/hadoop/apache-hive-1.2.2-bin/bin/hive   #客戶端訪問測試

Bash
hive> create database 52db; OK hive> show databases; OK 52db default twodb Time taken: 0.024 seconds, Fetched: 3 row(s)

image.png

#由上圖可以看到創建的數據庫都已經存在了hdfs對應的目錄下面。

2.8 語言手冊命令

Bash
quit/exit        #使用quit或exit離開交互式shell。 reset #將配置重置為默認值。在命令行中使用set命令或-hiveconf參數設置的任何配置參數都將重置為默認值。請注意,這不適用於在set命令中為密鑰名稱(由於歷史原因)使用“hiveconf:”前綴設置的配置參數。 set <key>=<value> #設置特定配置變量(鍵)的值。注意:如果拼錯變量名稱,CLI不會顯示錯誤。 set #打印由用戶或Hive覆蓋的配置變量的列表。 set -v #打印所有Hadoop和Hive配置變量。 add FILE[S] <filepath> <filepath>* add JAR[S] <filepath> <filepath>* add ARCHIVE[S] <filepath> <filepath>* #將一個或多個文件,jar或存檔添加到分布式緩存中的資源列表中。 add FILE[S] <ivyurl> <ivyurl>* add JAR[S] <ivyurl> <ivyurl>* add ARCHIVE[S]<ivyurl> <ivyurl>* #從Hive 1.2.0開始,使用形式為ivy://group:module:version?query_string的Ivy URL將一個或多個文件,jar或存檔添加到分布式緩存中的資源列表。 list FILE[S] list JAR[S] list ARCHIVE[S] #列出已添加到分布式緩存的資源。 list FILE[S] <filepath>* list JAR[S] <filepath>* list ARCHIVE[S] <filepath>* #檢查給定資源是否已經添加到分布式緩存中。 delete FILE[S] <filepath>* delete JAR[S] <filepath>* delete ARCHIVE[S] <filepath>* #從分布式緩存中刪除資源。 delete FILE[S] <ivyurl> <ivyurl>* delete JAR[S] <ivyurl> <ivyurl>* delete ARCHIVE[S] <ivyurl> <ivyurl>* #從Hive 1.2.0開始,從分布式緩存中刪除使用<ivyurl>添加的資源。 ! <command> #從Hive shell執行一個shell命令。 dfs <dfs command> #從Hive shell執行一個dfs命令。 <query string> #執行Hive查詢並將結果打印到標准輸出 source FILE <filepath> #在CLI中執行腳本文件。 compile `<groovy string>` AS GROOVY NAMED <name> #這允許內聯Groovy代碼被編譯並用作UDF(從Hive 0.13.0開始)。

用法舉例:

Bash
 hive> set mapred.reduce.tasks=32; hive> set; hive> select a.* from tab1; hive> !ls; hive> dfs -ls;

$ hive -H

Bash
usage: hive
-d,--define <key=value> #變量替換適用於配置單元命令。 例如 -d A = B或--define A = B --database <databasename> #指定要使用的數據庫 -e <quoted-query-string> #SQL從命令行 -f <filename> #來自文件的SQL -H,--help #打印幫助信息 --hiveconf <property=value> #使用給定屬性的值 --hivevar <key=value> #變量替換適用於配置單元命令。 例如 --hivevar A = B -i <filename> #初始化SQL文件 -S,--silent #交互式shell中的寂靜模式 -v,--verbose #詳細模式(echo向控制台執行SQL)

#HiveServer2(在Hive 0.11中引入)有自己的叫做Beeline的CLI,它是一個基於SQLLine的JDBC客戶端。 由於新的開發集中在HiveServer2上,Hive CLI很快將被棄用,以支持Beeline。

2.9 登錄Beeline的使用實例

#HiveServer2客戶端(beeline):https://cwiki.apache.org/confluence/display/Hive/HiveServer2+Clients#HiveServer2Clients-Beeline–NewCommandLineShell

Beeline工作模式有兩種,即本地嵌入模式和遠程模式。嵌入模式情況下,它返回一個嵌入式的Hive(類似於Hive CLI)。而遠程模式則是通過Thrift協議與某個單獨的HiveServer2進程進行連接通信。

服務端啟動服務(啟動ThifServer):

#正常的hive僅允許使用HiveQL執行查詢、更新等操作,並且該方式比較笨拙單一。幸好Hive提供了輕客戶端的實現,通過HiveServer或者HiveServer2,客戶端可以在不啟動CLI的情況下對Hive中的數據進行操作,

兩者都允許遠程客戶端使用多種編程語言如Java、Python向Hive提交請求,取回結果 使用jdbc協議連接hive的thriftserver服務器.

$ /home/hadoop/apache-hive/bin/hive --service hiveserver2 10000>/dev/null 2>/dev/null &
$ netstat  -lntup|grep 10000

Bash
tcp        0      0 0.0.0.0:10000           0.0.0.0:*               LISTEN      836/java

客戶端登錄:

$ /home/hadoop/apache-hive/bin/beeline

Bash
beeline> show databases; #得進行連接 #No current connection beeline> !connect jdbc:hive2://master.hadoop:10000 #連接hive服務端 #Connecting to jdbc:hive2://master.hadoop:10000 Enter username for jdbc:hive2://master.hadoop:10000: #輸入用戶名如果沒設置密碼回車就可 Enter password for jdbc:hive2://master.hadoop:10000: #輸入密碼如果沒有設置密碼回車就可 #Connected to: Apache Hive (version 1.2.2) #Driver: Hive JDBC (version 1.2.2) #Transaction isolation: TRANSACTION_REPEATABLE_READ 0: jdbc:hive2://master.hadoop:10000> show databases; #查看數據庫

圖片.png

自定義HiveServer2的用戶安全認證:http://lxw1234.com/archives/2016/01/600.htm

三、Hive基本操作

官網文檔:https://cwiki.apache.org/confluence/display/Hive/LanguageManual+DDL

3.1 創建/刪除/修改/使用數據庫

$ /home/hadoop/apache-hive-1.2.2-bin/bin/hive

創建數據庫:

Bash
hive> create database hivetest;

#上面是建立了一個新的數據庫hivetest,然后再HDFS的/user/hive/warehouse/中生成一個hivetest.db文件夾。

刪除數據庫:

Bash
hive> drop database hivetest; #刪除hivetest的數據庫,下面是提示 Moved: 'hdfs://mycluster/user/hive/warehouse/hivetest.db' to trash at: hdfs://mycluster/user/hadoop/.Trash/Current OK Time taken: 0.997 seconds

修改數據庫:

Bash
ALTER (DATABASE|SCHEMA) database_name SET DBPROPERTIES (property_name=property_value, ...); ALTER (DATABASE|SCHEMA) database_name SET OWNER [USER|ROLE] user_or_role; ALTER (DATABASE|SCHEMA) database_name SET LOCATION hdfs_path;

使用數據庫:

Bash
hive> show databases; #展示現在有的數據庫 hive> use twodb; #使用twodb數據庫

3.2 創建/刪除/查看表

創建表:

Bash
hive> create table t_order(id int,name string,ipaddr string); #創建了一個t_order表

圖片.png

#在hdfs的hivetest.db目錄下面會產生個新的目錄t_order。

刪除表:

Bash
hive> drop table t_order;

插入表:

Bash
hive> create table t_order(id int,name string,ipaddr string); hive> insert into t_order values(1,"master.hadoop","192.168.14.49"); #插入一條數據

insert操作會產生一個mr作業:

Bash
Query ID = hadoop_20171121151517_8fe24555-d798-4de2-9e7b-8587f50c9980 Total jobs = 3 Launching Job 1 out of 3 Number of reduce tasks is set to 0 since there's no reduce operator Starting Job = job_1510676201586_0004, Tracking URL = http://slave01.hadoop:8088/proxy/application_1510676201586_0004/ Kill Command = /home/hadoop/hadoop/bin/hadoop job -kill job_1510676201586_0004 Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0 2017-11-21 15:15:29,701 Stage-1 map = 0%, reduce = 0% 2017-11-21 15:15:40,402 Stage-1 map = 100%, reduce = 0%, Cumulative CPU 7.52 sec MapReduce Total cumulative CPU time: 7 seconds 520 msec Ended Job = job_1510676201586_0004 Stage-4 is selected by condition resolver. Stage-3 is filtered out by condition resolver. Stage-5 is filtered out by condition resolver. Moving data to: hdfs://mycluster/user/hive/warehouse/hivetest.db/t_order/.hive-staging_hive_2017-11-21_15-15-17_483_5747452280618734415-1/-ext-10000 Loading data to table hivetest.t_order Table hivetest.t_order stats: [numFiles=2, numRows=1, totalSize=262, rawDataSize=29] MapReduce Jobs Launched: Stage-Stage-1: Map: 1 Cumulative CPU: 7.52 sec HDFS Read: 3847 HDFS Write: 102 SUCCESS Total MapReduce CPU Time Spent: 7 seconds 520 msec OK Time taken: 25.685 seconds

圖片.png

圖片.png

查看表:

Bash
hive> select * from t_order; #查看t_order表,下面是輸出 OK 1 master.hadoop 192.168.14.49 Time taken: 0.409 seconds, Fetched: 10 row(s)

查看表結構:

hive> desc t_order;   #下面為輸出

Bash
OK
id int name string ipaddr string Time taken: 0.059 seconds, Fetched: 3 row(s)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM