apache hive 使用概述

1         產品概述

1.1  產品功能

        Apache Hive數據倉庫軟件提供對存儲在分佈式中的大型數據集的查詢和管理,它自己是創建在Apache Hadoop之上,主要提供如下功能:java

1. 它提供了一系列的工具,可用來對數據進行提取/轉化/加載(ETL);是一種能夠存儲、查詢和分析存儲在HDFS(或者HBase)中的大規模數據的機制;查詢是經過MapReduce來完成的(並非全部的查詢都須要MapReduce來完成,好比select * from XXX就不須要;在Hive0.11對相似select a,b from XXX的查詢經過配置也能夠不經過MapReduce來完成);node

2. Hive是一種創建在Hadoop文件系統上的數據倉庫架構,並對存儲在HDFS中的數據進行分析和管理;mysql

3. Hive定義了一種相似SQL的查詢語言,被稱爲HQL,對於熟悉SQL的用戶能夠直接利用Hive來查詢數據。同時,這個語言也容許熟悉MapReduce開發者們開發自定義的mappersreducers來處理內建的mappersreducers沒法完成的複雜的分析工做。Hive能夠容許用戶編寫本身定義的函數UDF,在查詢中使用。Hive中有3UDFUser Defined FunctionsUDF)、User Defined Aggregation FunctionsUDAF)、User Defined Table Generating FunctionsUDTF)。web

    如今,Hive已是一個成功的Apache項目,不少組織把它用做一個通用的、可伸縮的數據處理平臺。sql

        Hive和傳統的關係型數據庫有很大的區別,Hive將外部的任務解析成一個MapReduce可執行計劃,而啓動MapReduce是一個高延遲的一件事,每次提交任務和執行任務都須要消耗不少時間,這也就決定Hive只能處理一些高延遲的應用(若是想處理低延遲的應用,能夠考慮一下Hbase)。同時,因爲設計的目標不同,Hive目前還不支持事務;不能對錶數據進行修改。shell

1.2  Hive和傳統數據庫進行比較

        Hive在不少方面和RMDB相似,好比說它支持SQL接口;可是因爲其它底層設計的緣由,對HDFSMapreduce有很強的依賴,這也就意味這Hive的體系結構和RMDB有很大的區別。這些區別又間接的影響到Hive所支持的一些特性。數據庫

    在傳統的RMDB中,表的模式是在數據加載的時候強行肯定好的。若是在加載時發現數據不符合模式,則拒絕加載這些數據。而Hive在加載的過程當中不對數據進行任何的驗證操做,其只是簡單的將數據複製或者移動到表對應的目錄下面。從這方面來講,傳統數據庫在數據加載的過程當中比Hive要慢。可是由於傳統數據庫在數據加載過程當中能夠進行一些處理,好比對某一列創建索引等,這樣能夠提高數據的查詢性能。而在這方面Hive不行。express

比較項apache

SQLvim

HiveQL

ANSI SQL

支持

不徹底支持

更新

UPDATE\INSERT\DELETE

insert OVERWRITE\INTO TABLE

事務

支持

不支持

模式

寫模式

讀模式

數據保存

塊設備、本地文件系統

HDFS

延時

多表插入

不支持

支持

子查詢

徹底支持

只能用在From子句中

視圖

Updatable

Read-only

可擴展性

數據規模

……

……

……

    從上表能夠看出,Hive和傳統的數據庫仍是有不少的區別。

        HiveSQL方言通常被稱爲HiveQL,在下文咱們簡稱HQL。在上面咱們提到,HQL並不徹底支持SQL92標準。這個也是有緣由的。遵循SQL92Hive的設計開始就不是它的目標。

1.3 應用場景

        Hive目前主要應用在海量數據處理、數據挖掘、數據分析等方面,hive是針批量對長時間數據分析設計的,不能作交互式的實時查詢。

2         產品架構

        Hive產品架構以下所示:

        Hive架構圖中涉及服務、元數據、HdfsMapreduce等信息,下面分別進行說明:

2.1  服務

        hive有三種service,分別是clihiveserverhwi

1. cli是命令行工具,爲默認服務,啓動方式$HIVE_HOME/bin/hive $HIVE_HOME/bin/hive --service cli

2. hiverserver經過thrift對外提供服務,默認端口10000,啓動方式爲$HIVE_HOME/bin/hive--service hiveserver

3. hwiweb接口,能夠經過瀏覽器訪問hive,默認端口9999,啓動方式爲$HIVE_HOME/bin/hive--service hwi

    每一個服務間互相獨立,有各自的配置文件(配置metasotre/namenode/jobtracker),若是metasotre的配置同樣則物理上對應同一hive庫。

        Driver用於解釋、編譯、優化、執行HQL,每一個serviceDriver相互獨立。

        CLI爲用戶提供命令行接口,每一個CLI獨享配置,即在一個CLI裏修改配置不影響別的CLI

多個JDBC可同時連到同一HiveServer上,全部會話共享一份配置。(:0.9.0hiveserver配置已經從global降爲session,即每一個session的配置相互獨立)

     多個瀏覽器可同時連到同一HWI上,全部會話共享一份配置。

        Hive能夠在運行時用–service選項來明確指定使用的服務類型,能夠用下面的--service help來查看幫助,以下:

[wyp@master ~]$ hive --service help

Usage ./hive <parameters> --service serviceName <service parameters>

Service List: beeline cli help hiveserver2 hiveserver hwi jar lineage metastore metatool orcfiledump rcfilecat

Parameters parsed:

  --auxpath : Auxillary jars

  --config : Hive configuration directory

  --service : Starts specific service/component. cli is default

Parameters used:

  HADOOP_HOME or HADOOP_PREFIX : Hadoop install directory

  HIVE_OPT : Hive options

For help on a particular service:

  ./hive --service serviceName --help

Debug help:  ./hive --debug –help

    上面的輸出項Service List,裏面顯示出Hive支持的服務列表:beeline cli help hiveserver2 hiveserver hwi jar lineage metastore metatool orcfiledump rcfilecat,下面介紹最經常使用的一些服務。

1cli:這個就是Command Line Interface的簡寫,是Hive的命令行界面,用的比較多。這是默認的服務,直接能夠在命令行裏面使用。

2hiveserver:這個可讓Hive以提供Trift服務的服務器形式來運行,容許許多不一樣語言編寫的客戶端進行通訊。使用時須要啓動HiveServer服務以和客戶端聯繫,能夠經過設置HIVE_PORT環境變量來設置服務器所監聽的端口號,在默認的狀況下,端口爲10000。能夠經過下面方式來啓動hiveserver

[wyp@master ~]$  bin/hive --service hiveserver -p 10002

Starting Hive Thrift Server

其中-p參數也是用來指定監聽端口的。

3hwi:其實就是hive web interface的縮寫,它是HiveWeb接口,是hive cli的一個web替換方案。

4jar:與Hadoop jar等價的Hive的接口,這是運行類路徑中同時包含HadoopHive類的Java應用程序的簡便方式。

5metastore:在默認狀況下,metastoreHive服務運行在同一個進程中。使用這個服務,可讓metastore做爲一個單獨的進程運行,能夠經過METASTORE_PORT來指定監聽的端口號,具體以下所示:

2.2  元數據

        Hive的數據分爲表數據和元數據,表數據是Hive中表格(table)具備的數據;而元數據是用來存儲表的名字,表的列和分區及其屬性(是否爲外部表等),表的數據所在目錄等。

    元數據位置經過參數javax.jdo.option.ConnectionURL來指定,可在會話中自由修改。相關的參數包括:

javax.jdo.option.ConnectionDriverName           #數據庫驅動

javax.jdo.option.ConnectionURL                      #數據庫ip端口庫名等

javax.jdo.option.ConnectionUserName              #用戶名

javax.jdo.option.ConnectionPassword               #密碼

經過修改這些參數能夠在多個MetaStore間熱切換,可用於HA

2.3  NameNodeJobTracker

        NameNodefs.default.name指定,JobTrackermapred.job.tracker指定,這兩個參數均可以在會話中自由修改來指向不一樣的NameNodeJobTracker

    配合MetaStore能夠有多種組合出現,例如在同一個MetaStore裏讓table1的數據存在HDFS1,用JobTracker1計算,table2的數據存在HDFS2,用JobTracker2計算,或者讓兩個表都在JobTracker3上計算。

        NameNodeJobTracker最好指向同一個集羣,不然計算的時候須要跨集羣複製數據。

    在MetaStore存儲的是表數據文件的絕對路徑,小心其與NameNode/ JobTracker不在同一個集羣裏致使跨集羣複製。

    對hiveserverhwi配置的修改會做用到同一service上的全部會話。(:0.9.0hiveserver配置已經從global降爲session,即每一個session的配置相互獨立)

3         安裝部署

        Hive最新版本是apache-hive-0.13.1-bin.tar.gz,下載地址爲http://apache.fayea.com/apache-mirror/hive/hive-0.13.1/

    下載後,選個目錄,解壓,命令以下:

# tar -zxvf hive-0.10.0.tar.gz

    如今須要配置Hive,纔可以運行Hive。進入conf文件夾,將hive-default.xml.template文件的內容複製到hive-site.xml文件中,操做以下:

#cd conf/

#cp hive-default.xml.template hive-site.xml

    在hive-site.xml文件中進行以下配置:

<property>

<name>hive.metastore.warehouse.dir</name>

<value>/home/wyp/cloud/hive/warehouse</value>

<description>location of default database for the warehouse</description>

</property>

<property>

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

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&amp;createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

<property>

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

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

<description>Driver class name for a JDBC metastore</description>

</property>

<property>

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

<value>root</value>

<description>username to use against metastore database</description>

</property>

<property>

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

<value>123456</value>

<description>password to use against metastore database</description>

</property>

        Hive將元數據存儲在RDBMS中,好比MySQLDerby中。Hive默認是用Derby數據庫,這裏修改成MySQL(因此要確保電腦上已經安裝好了MySQL數據庫)。須要將mysql驅動jarmysql-connector-java-5.1.22-bin.jar拷貝到$HIVE_HOME/lib/目錄下。而後編輯/etc/profile文件,將Hivehome目錄添加進去,操做以下:

#sudo vim /etc/profile

    在其中添加下面語句,修改Hivehome路徑爲解壓的目錄:

export HIVE_HOME=/home/...hive-0.10.0

PATH=$PATH:$HIVE_HOME/bin

    最後讓上面的修改生效,請運行下面的命令:

#source /etc/profile

    如今能夠試一下,hive是否安裝好(須要啓動Hadoop,不然不能運行成功!):

#hive

hive>

    若是出現了上述狀況,說明hive安裝成功。

4         數據存儲模式

1. Hive的數據存儲

        Hive是基於Hadoop分佈式文件系統的,它的數據存儲在Hadoop分佈式文件系統中。Hive自己是沒有專門的數據存儲格式,也沒有爲數據創建索引,只須要在建立表的時候告訴Hive數據中的列分隔符和行分隔符,Hive就能夠解析數據。因此往Hive表裏面導入數據只是簡單的將數據移動到表所在的目錄中(若是數據是在HDFS上;但若是數據是在本地文件系統中,那麼是將數據複製到表所在的目錄中)。

        Hive中主要包含如下幾種數據模型:Table(表),External Table(外部表),Partition(分區),Bucket(桶)。

a. 表:Hive中的表和關係型數據庫中的表在概念上很相似,每一個表在HDFS中都有相應的目錄用來存儲表的數據,這個目錄能夠經過${HIVE_HOME}/conf/hive-site.xml配置文件中的hive.metastore.warehouse.dir屬性來配置,這個屬性默認的值是/user/hive/warehouse(這個目錄在HDFS上),咱們能夠根據實際的狀況來修改這個配置。若是我有一個表wyp,那麼在HDFS中會建立/user/hive/warehouse/wyp目錄(這裏假定hive.metastore.warehouse.dir配置爲/user/hive/warehouse);wyp表全部的數據都存放在這個目錄中。這個例外是外部表。

b.外部表:Hive中的外部表和表很相似,可是其數據不是放在本身表所屬的目錄中,而是存放到別處,這樣的好處是若是你要刪除這個外部表,該外部表所指向的數據是不會被刪除的,它只會刪除外部表對應的元數據;而若是你要刪除表,該表對應的全部數據包括元數據都會被刪除。

c.分區:在Hive中,表的每個分區對應表下的相應目錄,全部分區的數據都是存儲在對應的目錄中。好比wyp表有dtcity兩個分區,則對應dt=20131218,city=BJ對應表的目錄爲/user/hive/warehouse/dt=20131218/city=BJ,全部屬於這個分區的數據都存放在這個目錄中。

d.桶:對指定的列計算其hash,根據hash值切分數據,目的是爲了並行,每個桶對應一個文件(注意和分區的區別)。好比將wypid列分散至16個桶中,首先對id列的值計算hash,對應hash值爲016的數據存儲的HDFS目錄爲:/user/hive/warehouse/wyp/part-00000;而hash值爲2的數據存儲的HDFS 目錄爲:/user/hive/warehouse/wyp/part-00002

Hive數據抽象結構以下所示:


2.Hive的元數據

        Hive中的元數據包括表的名字,表的列和分區及其屬性,表的屬性(是否爲外部表等),表的數據所在目錄等。因爲Hive的元數據須要不斷的更新、修改,而HDFS系統中的文件是多讀少改的,這顯然不能將Hive的元數據存儲在HDFS中。目前Hive將元數據存儲在數據庫中,如MysqlDerby中。咱們能夠經過如下的配置來修改Hive元數據的存儲方式。

<property>

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

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8

&createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

<property>

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

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

<description>Driver class name for a JDBC metastore</description>

</property>

<property>

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

<value>root</value>

<description>username to use against metastore database</description>

</property>

<property>

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

<value>123456</value>

<description>password to use against metastore database</description>

</property>

    還須要將鏈接對應數據庫的依賴包複製到${HIVE_HOME}/lib目錄中,這樣才能將元數據存儲在對應的數據庫中。

5        基本操做

5.1  Hive內置數據類型

        Hive的內置數據類型能夠分爲兩大類:(1)基礎數據類型;(2)複雜數據類型。其中,基礎數據類型包括:TINYINTSMALLINTINTBIGINTBOOLEANFLOATDOUBLESTRINGBINARYTIMESTAMPDECIMALCHARVARCHARDATE。下面的表格列出這些基礎類型所佔的字節以及從什麼版本開始支持這些類型。

數據類型

所佔字節

開始支持版本

TINYINT

1byte-128 ~ 127


SMALLINT

2byte-32,768 ~ 32,767 


INT

4byte,-2,147,483,648 ~   2,147,483,647


BIGINT

8byte,-9,223,372,036,854,775,808   ~ 9,223,372,036,854,775,807


BOOLEAN



FLOAT

4byte雙精度


DOUBLE

8byte雙精度


STRING



BINARY


Hive0.8.0開始支持

TIMESTAMP


Hive0.8.0開始支持

DECIMAL


Hive0.11.0開始支持

CHAR


Hive0.13.0開始支持

VARCHAR


Hive0.12.0開始支持

DATE


Hive0.12.0開始支持

複雜類型包括ARRAY,MAP,STRUCT,UNION,這些複雜類型是由基礎類型組成的。

ARRAYARRAY類型是由一系列相同數據類型的元素組成,這些元素能夠經過下標來訪問。好比有一個ARRAY類型的變量fruits,它是由['apple','orange','mango']組成,那麼咱們能夠經過fruits[1]來訪問元素orange,由於ARRAY類型的下標是從0開始的;

MAPMAP包含key->value鍵值對,能夠經過key來訪問元素。好比」userlist」是一個map類型,其中usernamekeypasswordvalue;那麼咱們能夠經過userlist['username']來獲得這個用戶對應的password

STRUCTSTRUCT能夠包含不一樣數據類型的元素。這些元素能夠經過點語法的方式來獲得所須要的元素,好比user是一個STRUCT類型,那麼能夠經過user.address獲得這個用戶的地址。

UNION: UNIONTYPE,他是從Hive 0.7.0開始支持的。

建立一個包含複製類型的表格能夠以下:

CREATE TABLE employees (

    name STRING,

    salary FLOAT,

    subordinates ARRAY<STRING>,

    deductions MAP<STRING, FLOAT>,

    address STRUCT<street:STRING, city:STRING, state:STRING, zip:INT>

) PARTITIONED BY (country STRING, state STRING);

5.2  Hive參數配置方法

        Hive提供三種能夠改變環境變量的方法,分別是:(1)修改${HIVE_HOME}/conf/hive-site.xml配置文件;(2)命令行參數;(3)在已經進入cli時進行參數聲明。下面分別介紹這幾種設定。

方法一:

    在Hive中,全部的默認配置都在${HIVE_HOME}/conf/hive-default.xml文件中,若是須要對默認的配置進行修改,能夠建立一個hive-site.xml文件,放在${HIVE_HOME}/conf目錄下。裏面能夠對一些配置進行個性化設定。在hive-site.xml的格式以下:

<configuration>

    <property>

        <name>hive.metastore.warehouse.dir</name>

        <value>/user/hive/warehouse</value>

        <description>location of

              default database for the warehouse</description>

    </property>

</configuration>

    全部的配置都是放在<configuration></configuration>標籤之間,一個configuration標籤裏面能夠存在多個<property></property>標籤。<name>標籤裏面就是要設定屬性的名稱;<value>標籤裏面是要設定的值;<description>標籤描述這個屬性的做用。絕大多少配置都是在xml文件裏面配置的,由於在這裏作的配置都全局用戶都生效,並且是永久的。用戶自定義配置會覆蓋默認配置。另外,Hive也會讀入Hadoop的配置,由於Hive是做爲Hadoop的客戶端啓動的,Hive的配置會覆蓋Hadoop的配置。

方法二:

    在啓動Hive cli的時候進行配置,能夠在命令行添加-hiveconf param=value來設定參數,例如:

# hive --hiveconf mapreduce.job.queuename=queue1

    這樣在Hive中全部MapReduce做業都提交到隊列queue1中。這一設定對本次啓動的會話有效,下次啓動須要從新配置。

方法三:

    在已經進入cli時進行參數聲明,能夠在HQL中使用SET關鍵字設定參數,例如:

hive> set mapreduce.job.queuename=queue1;

    這樣也能達到方法二的效果。這種配置也是對本次啓動的會話有效,下次啓動須要從新配置。在HQL中使用SET關鍵字還能夠查看配置的值,以下:

hive> set mapreduce.job.queuename;

mapreduce.job.queuename=queue1

    咱們能夠獲得mapreduce.job.queuename=queue1。若是set後面什麼都不添加,這樣能夠查到Hive的全部屬性配置,以下:

hive> set;

datanucleus.autoCreateSchema=true

上述三種設定方式的優先級依次遞增。即參數聲明覆蓋命令行參數,命令行參數覆蓋配置文件設定。

5.3  Hive日誌調試

    在不少程序中,能夠經過輸出日誌的形式來獲得程序的運行狀況,經過這些輸出日誌來調試程序。

    在Hive中,使用的是Log4j來輸出日誌,默認狀況下,CLI是不能將日誌信息輸出到控制檯的。在Hive0.13.0以前版本,默認的日誌級別是WARN,從Hive0.13.0開始,默認的日誌級別是INFO。默認的日誌存放在/tmp/<user.name>文件夾的hive.log文件中,即/tmp/<user.name>/hive.log

    在默認的日誌級別狀況下,不能將DEBUG信息輸出,這樣一來出現的各類詳細的錯誤信息是不能輸出的。可是能夠經過如下兩種方式修改log4j輸出的日誌級別,從而利用這些調試日誌進行錯誤定位,具體作法以下:

# hive --hiveconf hive.root.logger=DEBUG,console

    或者在${HIVE_HOME}/conf/hive-log4j.properties文件中找到hive.root.logger屬性,並將其修改成下面的設置

hive.root.logger=DEBUG,console

    上面兩種方法的設置各有優劣,方法一的設定只是對本次會話有效,下次若是還想修改日誌輸出級別須要從新設定,可是不是每時每刻都須要修改日誌的輸出級別,因此在有時須要修改輸出的日誌級別,有時不須要的時候能夠用這種方法;方法二將日誌輸出級別設定到文件中去了,這個設定是對全部的用戶都生效,並且每次使用HQL的時候都會輸出一大堆的日誌,這種狀況適合那些無時無刻都須要HQL的運行日誌的用戶。

5.4  hiveQL插入語法

1. Insert基本語法格式爲:

INSERT OVERWRITE TABLE tablename [PARTITON(partcol1=val1,partclo2=val2)]select_statement FROM from_statement

示例:insert overwrite table test_insert select * from test_table;

2. 對多個表進行插入操做:

FROM fromstatte

INSERT OVERWRITE TABLE tablename1 [PARTITON(partcol1=val1,partclo2=val2)]select_statement1

INSERT OVERWRITE TABLE tablename2 [PARTITON(partcol1=val1,partclo2=val2)]select_statement2

示例:

from test_table

insert overwrite table test_insert1

select key

insert overwrite table test_insert2

select value;

insert的時候,from子句便可以放在select子句後面,也能夠放在 insert子句前面。

hive不支持用insert語句一條一條的進行插入操做,也不支持update操做。數據是以load的方式加載到創建好的表中。數據一旦導入就不能夠修改。

3.經過查詢將數據保存到filesystem

INSERT OVERWRITE [LOCAL] DIRECTORY directory SELECT.... FROM .....

導入數據到本地目錄:

insert overwrite local directory '/home/zhangxin/hive' select * from test_insert1;

產生的文件會覆蓋指定目錄中的其餘文件,即將目錄中已經存在的文件進行刪除。

導出數據到HDFS中:

insert overwrite directory '/user/zhangxin/export_test' select value from test_table;

同一個查詢結果能夠同時插入到多個表或者多個目錄中:

from test_insert1

insert overwrite local directory '/home/zhangxin/hive' select *

insert overwrite directory '/user/zhangxin/export_test' select value;

Hive insert into語句的標準語法以下:

用法一:

INSERT OVERWRITE TABLE tablename1 [PARTITION \

(partcol1=val1, partcol2=val2 ...) [IF NOT EXISTS]] \

select_statement1 FROM from_statement;

用法二:

INSERT INTO TABLE tablename1 [PARTITION \

(partcol1=val1, partcol2=val2 ...)] \

select_statement1 FROM from_statement;

舉例:

hive> insert into table cite

> select * from tt;

    這樣就會將tt表格裏面的數據追加到cite表格裏面。而且在cite數據存放目錄生成了一個新的數據文件,這個新文件是通過處理的,列之間的分割是cite表格的列分割符,而不是tt表格列的分隔符。

(1) 若是兩個表格的維度不同,將會插入錯誤:

hive> insert into table cite

> select * from cite_standby;

FAILED: SemanticException [Error 10044]: Line 1:18 Cannot insert into

target table because column number/types are different 'cite':

Table insclause-0 has 2 columns, but query has 1 columns.

    從上面錯誤提示看出,查詢的表格cite_standby只有一列,而目標表格(也就是須要插入數據的表格)有2列,因爲列的數目不同,致使了上面的語句不能成功運行,咱們須要保證查詢結果列的數目和須要插入數據表格的列數目一致,這樣才行。

(2) 在用extended關鍵字建立的表格上插入數據將會影響到其它的表格的數據,由於他們共享一份數據文件。

(3) 若是查詢出來的數據類型和插入表格對應的列數據類型不一致,將會進行轉換,可是不能保證轉換必定成功,好比若是查詢出來的數據類型爲int,插入表格對應的列類型爲string,能夠經過轉換將int類型轉換爲string類型;可是若是查詢出來的數據類型爲string,插入表格對應的列類型爲int,轉換過程可能出現錯誤,由於字母就不能夠轉換爲int,轉換失敗的數據將會爲NULL

(4) 能夠將一個表查詢出來的數據插入到原表中:

hive> insert into table cite

> select * from cite;

結果就是至關於複製了一份cite表格中的數據。

(5) insert overwrite的區別:

hive> insert overwrite table cite

> select * from tt;

上面的語句將會用tt表格查詢到的數據覆蓋cite表格已經存在的數據。

5.5  hiveQL刪除語法

hiveQL刪除語法以下所示:

hive> TRUNCATE TABLE t;

這樣將會刪掉表格t關聯的全部數據,但會保留表和metadata的完整性。

5.6  hiveQL執行文件

Hive能夠運行保存在文件裏面的一條或多條的語句,只要用-f參數,通常狀況下,保存這些Hive查詢語句的文件一般用.q或者.hql後綴名,可是這不是必須的,你也能夠保存你想要的後綴名。假設test文件裏面有一下的Hive查詢語句:

select * from p limit 10;

select count(*) from p;

那麼咱們能夠用下面的命令來查詢:

#bin/hive -f test

........這裏省略了一些輸出...........

OK

196 242 3   881250949   20131102    jx

186 302 3   891717742   20131102    jx

22  377 1   878887116   20131102    jx

244 51  2   880606923   20131102    jx

Time taken: 4.386 seconds, Fetched: 4 row(s)

........這裏省略了一些輸出...........

OK

4

Time taken: 16.284 seconds, Fetched: 1 row(s)

若是你配置好了Hive shell的路徑,你能夠用SOURCE命令來運行那個查詢文件:

[wyp@wyp hive-0.11.0-bin]$ hive

hive> source /home/.../test;

........這裏省略了一些輸出...........

........這裏省略了一些輸出...........

OK

196 242 3   881250949   20131102    jx

186 302 3   891717742   20131102    jx

22  377 1   878887116   20131102    jx

244 51  2   880606923   20131102    jx

Time taken: 4.386 seconds, Fetched: 4 row(s)

........這裏省略了一些輸出...........

OK

4

Time taken: 16.284 seconds, Fetched: 1 row(s)

6         數據導入導出

6.1  Hive數據導入的方式

Hive目前有四種導入數據的方式:

1)從本地文件系統中導入數據到Hive表;

2)從HDFS上導入數據到Hive表;

3)從別的表中查詢出相應的數據並導入到Hive表中;

4)在建立表的時候經過從別的表中查詢出相應的記錄並插入到所建立的表中。

6.1.1            本地導入

先在Hive中建表,以下:

hive> create table wyp

     > (id  int , name string,

     > age  int , tel string)

     > ROW FORMAT DELIMITED

     > FIELDS TERMINATED BY '\t'

     > STORED AS TEXTFILE;

OK

Time taken:  2.832   seconds

這個表很簡單,只有四個字段。本地文件系統中有個/home/wyp/wyp.txt文件,內容以下:

[wyp @master   ~]$ cat wyp.txt

1    wyp              25   13188888888888

2    test 30   13888888888888

3    zs    34   899314121

wyp.txt文件中的數據列之間是使用\t分割的,能夠經過下面的語句將這個文件裏面的數據導入到wyp表裏面,操做以下:

hive> load data local inpath  'wyp.txt'   into table wyp;

Copying data from file:/home/wyp/wyp.txt

Copying file: file:/home/wyp/wyp.txt

Loading data to table  default .wyp

Table  default .wyp stats:

[num_partitions:  0 , num_files:  1 , num_rows:  0 , total_size:  67 ]

OK

Time taken:  5.967   seconds

這樣就將wyp.txt裏面的內容導入到wyp表裏面去了,能夠到wyp表的數據目錄下查看,以下命令:

hive> dfs -ls /user/hive/warehouse/wyp ;

Found  1   items

-rw-r--r-- 3   wyp supergroup  67   2014 - 02 - 19   18 : 23   /hive/warehouse/wyp/wyp.txt

數據的確導入到wyp表裏面去了。

和關係型數據庫不同,Hive如今還不支持在insert語句裏面直接給出一組記錄的文字形式,也就是說,Hive並不支持INSERT INTO .... VALUES形式的語句。

6.1.2            HDFS導入

從本地文件系統中將數據導入到Hive表的過程當中,實際上是先將數據臨時複製到HDFS的一個目錄下(典型的狀況是複製到上傳用戶的HDFS home目錄下,好比/home/wyp/),而後再將數據從那個臨時目錄下移動(注意,這裏說的是移動,不是複製!)到對應的Hive表的數據目錄裏面。既然如此,那麼Hive確定支持將數據直接從HDFS上的一個目錄移動到相應Hive表的數據目錄下,假設有下面這個文件/home/wyp/add.txt,具體的操做以下:

[wyp@master /home/q/hadoop-2.2.0]$ bin/hadoop fs -cat /home/wyp/add.txt

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

上面是須要插入數據的內容,這個文件是存放在HDFS/home/wyp目錄(和本地導入的不一樣,本地導入中提到的文件是存放在本地文件系統上)裏面,能夠經過下面的命令將這個文件裏面的內容導入到Hive表中,具體操做以下:

hive> load data inpath '/home/wyp/add.txt' into table wyp;

Loading data to table default.wyp

Table default.wyp stats:

[num_partitions: 0, num_files: 2, num_rows: 0, total_size: 215]

OK

Time taken: 0.47 seconds

 

hive> select * from wyp;

OK

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

1       wyp     25      13188888888888

2       test    30      13888888888888

3       zs      34      899314121

Time taken: 0.096 seconds, Fetched: 7 row(s)

從上面的執行結果能夠看到,數據的確導入到wyp表中了!請注意load data inpath /home/wyp/add.txt into table wyp;裏面是沒有local這個單詞的,這個是和本地導入方式的區別。

6.1.3            別的表查詢導入

假設Hive中有test表,其建表語句以下所示:

hive> create table test(

    > id int, name string

    > ,tel string)

    > partitioned by

    > (age int)

    > ROW FORMAT DELIMITED

    > FIELDS TERMINATED BY '\t'

    > STORED AS TEXTFILE;

OK

Time taken: 0.261 seconds

大致和wyp表的建表語句相似,只不過test表裏面用age做爲了分區字段。下面語句將wyp表中的查詢結果插入到test表中:

hive> insert into table test

    > partition (age='25')

    > select id, name, tel

    > from wyp;

#################################################################

           這裏輸出了一堆Mapreduce任務信息,這裏省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 310 msec

OK

Time taken: 19.125 seconds

hive> select * from test;

OK

5       wyp1    131212121212    25

6       wyp2    134535353535    25

7       wyp3    132453535353    25

8       wyp4    154243434355    25

1       wyp     13188888888888  25

2       test    13888888888888  25

3       zs      899314121       25

Time taken: 0.126 seconds, Fetched: 7 row(s)

經過上面的輸出,咱們能夠看到從wyp表中查詢出來的東西已經成功插入到test表中去了!若是目標表(test)中不存在分區字段,能夠去掉partition (age=25)語句。固然,也能夠在select語句裏面經過使用分區值來動態指明分區:

hive> set hive.exec.dynamic.partition.mode=nonstrict;

hive> insert into table test

    > partition (age)

    > select id, name,

    > tel, age

    > from wyp;

#################################################################

           這裏輸出了一堆Mapreduce任務信息,這裏省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 510 msec

OK

Time taken: 17.712 seconds

hive> select * from test;

OK

5       wyp1    131212121212    23

6       wyp2    134535353535    24

7       wyp3    132453535353    25

1       wyp     13188888888888  25

8       wyp4    154243434355    26

2       test    13888888888888  30

3       zs      899314121       34

Time taken: 0.399 seconds, Fetched: 7 row(s)

這種方法叫作動態分區插入,可是Hive中默認是關閉的,因此在使用前須要先把hive.exec.dynamic.partition.mode設置爲nonstrict。固然,Hive也支持insert overwrite方式來插入數據,從字面能夠看出,overwrite是覆蓋的意思,執行完這條語句的時候,相應數據目錄下的數據將會被覆蓋,而insert into則不會。例子以下:

hive> insert overwrite table test

    > PARTITION (age)

    > select id, name, tel, age

    > from wyp;

Hive還支持多表插入,在Hive中,能夠把insert語句倒過來,把from放在最前面,它的執行效果和放在後面是同樣的,以下:

hive> show create table test3;

OK

CREATE  TABLE test3(

  id int,

  name string)

Time taken: 0.277 seconds, Fetched: 18 row(s)

hive> from wyp

    > insert into table test

    > partition(age)

    > select id, name, tel, age

    > insert into table test3

    > select id, name

    > where age>25;

 

hive> select * from test3;

OK

8       wyp4

2       test

3       zs

Time taken: 4.308 seconds, Fetched: 3 row(s)

能夠在同一個查詢中使用多個insert子句,這樣只須要掃描一遍源表就能夠生成多個不相交的輸出。

6.1.4            建立表時導入

在實際狀況中,表的輸出結果可能太多,不適於顯示在控制檯上,這時候,將Hive的查詢輸出結果直接存在一個新的表中是很是方便的,稱這種狀況爲CTAScreate table as select)以下:

hive> create table test4

    > as

    > select id, name, tel

    > from wyp;

hive> select * from test4;

OK

5       wyp1    131212121212

6       wyp2    134535353535

7       wyp3    132453535353

8       wyp4    154243434355

1       wyp     13188888888888

2       test    13888888888888

3       zs      899314121

Time taken: 0.089 seconds, Fetched: 7 row(s)

數據就插入到test4表中去了,CTAS操做是原子的,所以若是select查詢因爲某種緣由而失敗,新表是不會建立的。

6.2  Hive數據導出的方式

Hive根據導出的地方不一樣能夠將導出方式分爲三種:(1)導出到本地文件系統;(2)導出到HDFS中;(3)導出到Hive的另外一個表中,下面逐一介紹。

6.2.1            導出到本地文件系統

hive> insert overwrite local directory '/home/wyp/wyp'

    > select * from wyp;

這條HQL的執行須要啓用Mapreduce完成,運行完這條語句以後,將會在本地文件系統的/home/wyp/wyp目錄下生成文件,這個文件是Reduce產生的結果(這裏生成的文件名是000000_0),咱們能夠看看這個文件的內容:

[wyp@master ~/wyp]$ vim 000000_0

5^Awyp1^A23^A131212121212

6^Awyp2^A24^A134535353535

7^Awyp3^A25^A132453535353

8^Awyp4^A26^A154243434355

1^Awyp^A25^A13188888888888

2^Atest^A30^A13888888888888

3^Azs^A34^A899314121

能夠看出,這是wyp表中的全部數據。數據中的列與列之間的分隔符是^A(ascii碼是\00001)

Hive 0.11.0版本以前,數據的導出是不能指定列之間的分隔符的,只能用默認的列分隔符,也就是上面的^A來分割,這樣導出來的數據很不直觀,看起來很不方便。

若是用的Hive版本是0.11.0和以後版本,能夠在導出數據的時候來指定列之間的分隔符,操做以下:

hive> insert overwrite local directory '/home/yangping.wu/local'

    > row format delimited

    > fields terminated by '\t'

    > select * from wyp;

 

 [wyp@master ~/local]$ vim 000000_0

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

1       wyp     25      13188888888888

2       test    30      13888888888888

3       zs      34      899314121

其實,還能夠用hive-e-f參數來導出數據。其中-e表示後面直接接帶雙引號的sql語句;而-f是接一個文件,文件的內容爲一個sql語句,以下:

[wyp@master ~/local]$  hive -e "select * from wyp" >> local/wyp.txt

[wyp@master ~/local]$cat wyp.txt

5       wyp1    23      131212121212

6       wyp2    24      134535353535

7       wyp3    25      132453535353

8       wyp4    26      154243434355

1       wyp     25      13188888888888

2       test    30      13888888888888

3       zs      34      899314121

獲得的結果也是用\t分割的。也能夠用-f參數實現:

[wyp@master ~/local]$ cat wyp.sql

select * from wyp

[wyp@master ~/local]$ hive -f wyp.sql >> local/wyp2.txt

上述語句獲得的結果也是\t分割的。

6.2.2            導出到HDFS

和導入數據到本地文件系統同樣的簡單,能夠用下面的語句實現:

hive> insert overwrite directory '/home/wyp/hdfs'

    > select * from wyp;

將會在HDFS/home/wyp/hdfs目錄下保存導出來的數據。注意,和導出文件到本地文件系統的HQL少一個local,數據的存放路徑就不同了。

6.2.3            導出到Hive的另外一個表中

hive> insert into table test

    > partition (age='25')

    > select id, name, tel

    > from wyp;

#################################################################

           這裏輸出了一堆Mapreduce任務信息,這裏省略

#################################################################

Total MapReduce CPU Time Spent: 1 seconds 310 msec

OK

Time taken: 19.125 seconds

hive> select * from test;

OK

5       wyp1    131212121212    25

6       wyp2    134535353535    25

7       wyp3    132453535353    25

8       wyp4    154243434355    25

1       wyp     13188888888888  25

2       test    13888888888888  25

3       zs      899314121       25

Time taken: 0.126 seconds, Fetched: 7 row(s)

其實就是講hive中一個表的內容導入到另外一個表中。

7         Hive索引

索引是標準的數據庫技術,hive 0.7版本以後支持索引。Hive提供有限的索引功能,這不像傳統的關係型數據庫那樣有(key)」的概念,用戶能夠在某些列上建立索引來加速某些操做,給一個表建立的索引數據被保存在另外的表中。 Hive的索引功能如今還相對較晚,提供的選項還較少。可是,索引被設計爲可以使用內置的可插拔的java代碼來定製,用戶能夠擴展這個功能來知足本身的需求。用戶可使用EXPLAIN語法來分析HiveQL語句是否可使用索引來提高用戶查詢的性能。像RDBMS中的索引同樣,須要評估索引建立的是否合理,畢竟,索引須要更多的磁盤空間,而且建立維護索引也會有必定的代價。 用戶必需要權衡從索引獲得的好處和代價。

下面介紹建立索引的方法:

1. 先建立表:

hive> create table a3( id int, name string)

> ROW FORMAT DELIMITED

> FIELDS TERMINATED BY '\t'

> STORED AS TEXTFILE;

2. 導入數據:

hive> load data local inpath 'apache-hive-0.13.1-bin/a21.txt'

    > overwrite into table a3;                              

Copying data from file:/usr/local/apache-hive-0.13.1-bin/a21.txt

Copying file: file:/usr/local/apache-hive-0.13.1-bin/a21.txt

Loading data to table default.a3

rmr: DEPRECATED: Please use 'rm -r' instead.

Deleted hdfs://localhost:9000/user/hive/warehouse/a3

Table default.a3 stats: [numFiles=1, numRows=0, totalSize=169, rawDataSize=0]

OK

Time taken: 0.468 seconds

3. 建立索引以前測試

hive> select * from a3 where id=28;

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Starting Job = job_1414112118511_0001, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0001/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job  -kill job_1414112118511_0001

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0

2014-10-24 09:12:11,220 Stage-1 map = 0%,  reduce = 0%

2014-10-24 09:12:16,404 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.13 sec

MapReduce Total cumulative CPU time: 1 seconds 130 msec

Ended Job = job_1414112118511_0001

MapReduce Jobs Launched:

Job 0: Map: 1   Cumulative CPU: 1.13 sec   HDFS Read: 375 HDFS Write: 8 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 130 msec

OK

28      fdah

Time taken: 14.007 seconds, Fetched: 1 row(s)

一共用了14.007s

4. user建立索引

hive> create index a3_index on table a3(id)

    > as 'org.apache.hadoop.hive.ql.index.compact.CompactIndexHandler'

    > with deferred rebuild

    > in table a3_index_table;

OK

Time taken: 0.292 seconds

hive> alter index a3_index on a3 rebuild

    > ;

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks not specified. Estimated from input data size: 1

In order to change the average load for a reducer (in bytes):

  set hive.exec.reducers.bytes.per.reducer=<number>

In order to limit the maximum number of reducers:

  set hive.exec.reducers.max=<number>

In order to set a constant number of reducers:

  set mapreduce.job.reduces=<number>

Starting Job = job_1414112118511_0002, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0002/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job  -kill job_1414112118511_0002

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 1

2014-10-24 09:13:52,094 Stage-1 map = 0%,  reduce = 0%

2014-10-24 09:13:57,265 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 0.75 sec

2014-10-24 09:14:03,479 Stage-1 map = 100%,  reduce = 100%, Cumulative CPU 1.81 sec

MapReduce Total cumulative CPU time: 1 seconds 810 msec

Ended Job = job_1414112118511_0002

Loading data to table default.a3_index_table

rmr: DEPRECATED: Please use 'rm -r' instead.

Deleted hdfs://localhost:9000/user/hive/warehouse/a3_index_table

Table default.a3_index_table stats: [numFiles=1, numRows=20, totalSize=1197, rawDataSize=1177]

MapReduce Jobs Launched:

Job 0: Map: 1  Reduce: 1   Cumulative CPU: 1.81 sec   HDFS Read: 375 HDFS Write: 1277 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 810 msec

OK

Time taken: 17.976 seconds

hive> select * from a3_index_table;

OK

1       hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [0]

2       hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [6]

3       hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [12]

6       hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [40]

8       hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [18]

12      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [46]

18      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [54]

21      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [22]

28      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [128]

78      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [119]

83      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [136]

98      hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [153]

123     hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [27]

129     hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [161]

234     hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [80,109]

812     hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [144]

891     hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [34]

1231    hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [70,88]

2134    hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [61]

7897    hdfs://localhost:9000/user/hive/warehouse/a3/a21.txt    [98]

Time taken: 0.041 seconds, Fetched: 20 row(s)

這樣對user表建立了一個索引。

5、對建立索引後的user再進行測試

hive> select * from a3 where id=28;                                  

Total jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Starting Job = job_1414112118511_0003, Tracking URL = http://h77.hadoop.org:8088/proxy/application_1414112118511_0003/

Kill Command = /usr/local/hadoop-2.4.1/bin/hadoop job  -kill job_1414112118511_0003

Hadoop job information for Stage-1: number of mappers: 1; number of reducers: 0

2014-10-24 09:15:40,439 Stage-1 map = 0%,  reduce = 0%

2014-10-24 09:15:46,617 Stage-1 map = 100%,  reduce = 0%, Cumulative CPU 1.21 sec

MapReduce Total cumulative CPU time: 1 seconds 210 msec

Ended Job = job_1414112118511_0003

MapReduce Jobs Launched:

Job 0: Map: 1   Cumulative CPU: 1.21 sec   HDFS Read: 375 HDFS Write: 8 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 210 msec

OK

28      fdah

Time taken: 11.924 seconds, Fetched: 1 row(s)

時間用了11.924s比沒有建立索引的效果好些,數據量大的時候效果會更明顯。

8         JDBC鏈接Hive Server

能夠經過CLIClientWeb UIHive提供的用戶接口來和Hive通訊,但這三種方式最經常使用的是CLIClientHive的客戶端,用來鏈接至Hive Server。在啓動Client模式的時候,須要指出Hive Server所在節點,而且在該節點啓動Hive ServerWUI是經過瀏覽器訪問 Hive。下面介紹經過HiveServer來操做Hive

Hive提供了JDBC驅動,使得咱們能夠用Java代碼來鏈接Hive並進行一些類關係型數據庫的SQL語句查詢等操做。同關係型數據庫同樣,也須要將Hive的服務打開;在Hive 0.11.0版本以前,只有HiveServer服務可用,得在程序操做Hive以前,在安裝Hive的服務器上打開HiveServer服務,以下所示:

#bin/hive --service hiveserver -p 10002

Starting Hive Thrift Server

上面表明你已經成功的在端口爲10002(默認的端口是10000)啓動了hiveserver服務。這時候,你就能夠經過Java代碼來鏈接hiveserver,代碼以下:

import java.sql.SQLException;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.Statement;

import java.sql.DriverManager;

 

public class Testmzl {

 

       private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";

 

       public static void main(String[] args) throws SQLException {

              try {

                     Class.forName(driverName);

              } catch (ClassNotFoundException e) {

                     e.printStackTrace();

                     System.exit(1);

              }

 

              Connection con = DriverManager.getConnection(

                            "jdbc:hive://192.168.1.77:10002/default", "", "");

              Statement stmt = con.createStatement();

              String tableName = "wyp";

              stmt.execute("drop table if exists " + tableName);

              stmt.execute("create table " + tableName + " (key int, value string)");

              System.out.println("Create table success!");

              // show tables

              String sql = "show tables";

              System.out.println("Running: " + sql);

              ResultSet res = stmt.executeQuery(sql);

              while (res.next()) {

                     System.out.println(res.getString(1));

              }

 

              // describe table

              sql = "describe " + tableName;

              System.out.println("Running: " + sql);

              res = stmt.executeQuery(sql);

              while (res.next()) {

                     System.out.println(res.getString(1) + "\t" + res.getString(2));

              }

 

              sql = "select * from " + tableName;

              res = stmt.executeQuery(sql);

              while (res.next()) {

                     System.out.println(String.valueOf(res.getInt(1)) + "\t"

                                   + res.getString(2));

              }

 

              sql = "select count(1) from " + tableName;

              System.out.println("Running: " + sql);

              res = stmt.executeQuery(sql);

              while (res.next()) {

                     System.out.println(res.getString(1));

              }

       }

}

編譯上面的代碼,以後就能夠運行,結果以下:

Create table success!

Running: show tables 'wyphao'

wyphao

Running: describe wyphao

key                     int               

value                   string            

Running: select count(1) from wyphao

0

上面用Java鏈接HiveServer,而HiveServer自己存在不少問題(好比:安全性、併發性等);針對這些問題,Hive0.11.0版本提供了一個全新的服務:HiveServer2,這個很好的解決HiveServer存在的安全性、併發性等問題。這個服務啓動程序在${HIVE_HOME}/bin/hiveserver2裏面,能夠經過下面的方式來啓動HiveServer2服務:

$HIVE_HOME/bin/hiveserver2

也能夠經過下面的方式啓動HiveServer2

$HIVE_HOME/bin/hive --service hiveserver2

兩種方式效果同樣。可是以前的java程序須要修改兩個地方,以下所示:

private static String driverName = "org.apache.hadoop.hive.jdbc.HiveDriver";

改成

private static String driverName = "org.apache.hive.jdbc.HiveDriver";

 

Connection con = DriverManager.getConnection("jdbc:hive://localhost:10002/default", "", "");

改成

Connection con = DriverManager.getConnection("jdbc:hive2://localhost:10000/default", "", "");

其餘的不變就能夠了。

 

9         常見問題

9.1  disabled stack guard

在安裝運行hadoop時會出現下面的錯誤:

Hadoop 2.2.0 - warning: You have loaded library /home/hadoop/2.2.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard.

具體出錯內容以下:

Unable to load native-hadoop library for your platform... using builtin-java classes where applicable

Starting namenodes on [Java HotSpot(TM) 64-Bit Server VM warning: You have loaded library /home/hadoop/2.2.0/lib/native/libhadoop.so.1.0.0 which might have disabled stack guard. The VM will try to fix the stack guard now.

It's highly recommended that you fix the library with 'execstack -c <libfile>', or link it with '-z noexecstack'.

localhost]

sed: -e expression #1, char 6: unknown option to `s'

HotSpot(TM): ssh: Could not resolve hostname HotSpot(TM): Name or service not known

64-Bit: ssh: Could not resolve hostname 64-Bit: Name or service not known

Java: ssh: Could not resolve hostname Java: Name or service not known

Server: ssh: Could not resolve hostname Server: Name or service not known

VM: ssh: Could not resolve hostname VM: Name or service not known

解決方法:

[root@h77 hadoop-2.4.1]#vim etc/hadoop/hadoop-env.sh

HADOOP_PREFIX變量的定義後面,HADOOP_OPTS變量的定義前面添加下列變量:

export HADOOP_COMMON_LIB_NATIVE_DIR=${HADOOP_PREFIX}/lib/native

export HADOOP_OPTS="-Djava.library.path=$HADOOP_PREFIX/lib"

9.2  javax.jdo.option.ConnectionURL配置的問題

Hive安裝過程當中出現 The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.問題,具體以下所示:

[Fatal Error] hive-site.xml:132:95: The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.

14/10/23 11:15:04 FATAL conf.Configuration: error parsing conf file:/usr/local/apache-hive-0.13.1-bin/conf/hive-site.xml

org.xml.sax.SAXParseException; systemId: file:/usr/local/apache-hive-0.13.1-bin/conf/hive-site.xml; lineNumber: 132; columnNumber: 95; The reference to entity "createDatabaseIfNotExist" must end with the ';' delimiter.

顯示以下所示:

由於hive-site.xml中的javax.jdo.option.ConnectionURL配置項引發的,以下所示:

<property>

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

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

正確配置以下:

<property>

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

<value>jdbc:mysql://localhost:3306/hive_hdp?characterEncoding=UTF-8&amp;createDatabaseIfNotExist=true</value>

<description>JDBC connect string for a JDBC metastore</description>

</property>

這是由於xml文件中的編碼規則引發的。

xml文件中有如下幾類字符要進行轉義替換以下表所示:

符號

Xml表示

含義

&lt;

小於號

&gt;

大於號

&amp;

&

&apos;

'

單引號

&quot;

"

雙引號

因此javax.jdo.option.ConnectionURL項中的&符號須要用&amp;表示。

10         Hive優化

10.1  簡單查詢不啓用Mapreduce job

若是你想查詢某個表的某一列,Hive默認是會啓用MapReduce Job來完成這個任務:

hive> SELECT id, money FROM m limit 10;

Total MapReduce jobs = 1

Launching Job 1 out of 1

Number of reduce tasks is set to 0 since there's no reduce operator

Cannot run job locally: Input Size (= 235105473) is larger than

hive.exec.mode.local.auto.inputbytes.max (= 134217728)

Starting Job = job_1384246387966_0229, Tracking URL =

 

http://l-datalogm1.data.cn1:9981/proxy/application_1384246387966_0229/

 

Kill Command = /home/q/hadoop-2.2.0/bin/hadoop job

-kill job_1384246387966_0229

hadoop job information for Stage-1: number of mappers: 1;

number of reducers: 0

2013-11-13 11:35:16,167 Stage-1 map = 0%,  reduce = 0%

2013-11-13 11:35:21,327 Stage-1 map = 100%,  reduce = 0%,

Cumulative CPU 1.26 sec

2013-11-13 11:35:22,377 Stage-1 map = 100%,  reduce = 0%,

Cumulative CPU 1.26 sec

MapReduce Total cumulative CPU time: 1 seconds 260 msec

Ended Job = job_1384246387966_0229

MapReduce Jobs Launched:

Job 0: Map: 1   Cumulative CPU: 1.26 sec 

HDFS Read: 8388865 HDFS Write: 60 SUCCESS

Total MapReduce CPU Time Spent: 1 seconds 260 msec

OK

1       122

1       185

1       231

1       292

1       316

1       329

1       355

1       356

1       362

1       364

Time taken: 16.802 seconds, Fetched: 10 row(s)

啓用MapReduce Job會消耗系統開銷,對於這個問題,從Hive0.10.0版本開始,對於簡單的不須要聚合的相似SELECT <col> from <table> LIMIT n語句,不須要起MapReduce job,直接經過Fetch task獲取數據,能夠經過下面幾種方法實現:

方法一:

hive> set hive.fetch.task.conversion=more;

hive> SELECT id, money FROM m limit 10;

OK

1       122

1       185

1       231

1       292

1       316

1       329

1       355

1       356

1       362

1       364

Time taken: 0.138 seconds, Fetched: 10 row(s)

上面set hive.fetch.task.conversion=more;開啓了Fetch任務,因此對於上述簡單的列查詢再也不啓用MapReduce job

方法二:

bin/hive --hiveconf hive.fetch.task.conversion=more

方法三:

上面的兩種方法均可以開啓了Fetch任務,可是都是臨時起做用的;若是你想一直啓用這個功能,能夠在${HIVE_HOME}/conf/hive-site.xml裏面加入如下配置:

<property>

<name>hive.fetch.task.conversion</name>

<value>more</value>

<description>Some select queries can be converted to single FETCH task

minimizing latency.Currently the query should be single

sourced not having any subquery and should not have

any aggregations or distincts (which incurrs RS),

lateral views and joins.

1. minimal : SELECT STAR, FILTER on partition columns, LIMIT only

2. more    : SELECT, FILTER, LIMIT only (+TABLESAMPLE, virtual columns)

</description>

</property>

這樣就能夠長期啓用Fetch任務了。

11         參考博文

本文主要參考下面的博文:

http://www.iteblog.com/archives/category/hive

相關文章
相關標籤/搜索